Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

I'm using "new" to allocate a 4-dimensional array, however, when I checked the actual size of memory available, the memory consumed by the array allocation is not what I expected.

Here's the code:

...

MEMORYSTATUS stat;

GlobalMemoryStatus (&stat);

printf("beginning memory: %dBytes\n", stat.dwAvailPhys);

int calc_tbl = 13;

int** MaxVal = new int*[calc_tbl]; //collect attribute MaxVals

for (int i=0; i<calc_tbl; i++)

MaxVal[i] = new int[2];

MaxVal[0][0] = MaxVal[0][1] = 8;

MaxVal[1][0] = MaxVal[1][1] = 52342;

MaxVal[2][0] = MaxVal[2][1] = 2646689;

MaxVal[3][0] = MaxVal[3][1] = 2971;

MaxVal[4][0] = MaxVal[4][1] = 2871;

MaxVal[5][0] = MaxVal[5][1] = 3;

MaxVal[6][0] = MaxVal[6][1] = 1636;

MaxVal[7][0] = MaxVal[7][1] = 1597;

MaxVal[8][0] = 817;

MaxVal[8][1] = 837;

MaxVal[9][0] = MaxVal[9][1] = 4;

MaxVal[10][0] = MaxVal[10][1] = 1273392;

MaxVal[11][0] = MaxVal[11][1] = 1557;

MaxVal[12][0] = MaxVal[12][1] = 6;

//initialize Freq[tblNo][branchNo][val][class]

float**** Freq = new float***[calc_tbl];

for (i=0; i<calc_tbl; i++)

{

Freq[i] = new float**[2];

for (int b=0; b<2; b++)

{

Freq[i][b] = new float*[MaxVal[i][b]];

for (int tt=0; tt<MaxVal[i][b]; tt++)

Freq[i][b][tt] = new float[3];

}

GlobalMemoryStatus (&stat);

printf("after initial Freq[%d] memory: %dBytes\n", i, stat.dwAvailPhys);

}

...

The available memory after each allocation is much less than what I expected for my array allocation. Why? The problem is, my memory runs out when I thought I should still have enough memory.

Here's the code:

...

MEMORYSTATUS stat;

GlobalMemoryStatus (&stat);

printf("beginning memory: %dBytes\n", stat.dwAvailPhys);

int calc_tbl = 13;

int** MaxVal = new int*[calc_tbl]; //collect attribute MaxVals

for (int i=0; i<calc_tbl; i++)

MaxVal[i] = new int[2];

MaxVal[0][0] = MaxVal[0][1] = 8;

MaxVal[1][0] = MaxVal[1][1] = 52342;

MaxVal[2][0] = MaxVal[2][1] = 2646689;

MaxVal[3][0] = MaxVal[3][1] = 2971;

MaxVal[4][0] = MaxVal[4][1] = 2871;

MaxVal[5][0] = MaxVal[5][1] = 3;

MaxVal[6][0] = MaxVal[6][1] = 1636;

MaxVal[7][0] = MaxVal[7][1] = 1597;

MaxVal[8][0] = 817;

MaxVal[8][1] = 837;

MaxVal[9][0] = MaxVal[9][1] = 4;

MaxVal[10][0] = MaxVal[10][1] = 1273392;

MaxVal[11][0] = MaxVal[11][1] = 1557;

MaxVal[12][0] = MaxVal[12][1] = 6;

//initialize Freq[tblNo][branchNo][val]

float**** Freq = new float***[calc_tbl];

for (i=0; i<calc_tbl; i++)

{

Freq[i] = new float**[2];

for (int b=0; b<2; b++)

{

Freq[i][b] = new float*[MaxVal[i][b]];

for (int tt=0; tt<MaxVal[i][b]; tt++)

Freq[i][b][tt] = new float[3];

}

GlobalMemoryStatus (&stat);

printf("after initial Freq[%d] memory: %dBytes\n", i, stat.dwAvailPhys);

}

...

The available memory after each allocation is much less than what I expected for my array allocation. Why? The problem is, my memory runs out when I thought I should still have enough memory.

Experts Exchange Solution brought to you by

Enjoy your complimentary solution view.

Get every solution instantly with premium.
Start your 7-day free trial.

I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

The following approach does 13x2=26 calls to new and makes use of automatic variables for the MaxVal 2D array:

--------8<--------

const int tables = 13;

const int branches = 2;

const int classes = 3;

struct Classes {

float score[classes]; /* I'm guessing this contains scores?! */

};

int main()

{

int MaxVal[tables][branches];

MaxVal[0][0] = MaxVal[0][1] = 8;

MaxVal[1][0] = MaxVal[1][1] = 52342;

MaxVal[2][0] = MaxVal[2][1] = 2646689;

MaxVal[3][0] = MaxVal[3][1] = 2971;

MaxVal[4][0] = MaxVal[4][1] = 2871;

MaxVal[5][0] = MaxVal[5][1] = 3;

MaxVal[6][0] = MaxVal[6][1] = 1636;

MaxVal[7][0] = MaxVal[7][1] = 1597;

MaxVal[8][0] = 817;

MaxVal[8][1] = 837;

MaxVal[9][0] = MaxVal[9][1] = 4;

MaxVal[10][0] = MaxVal[10][1] = 1273392;

MaxVal[11][0] = MaxVal[11][1] = 1557;

MaxVal[12][0] = MaxVal[12][1] = 6;

/* Allocate */

Classes* Freq[tables][branches];

for (int table = 0;table < tables;table++)

for (int branch = 0;branch < branches;branch++)

Freq[table][branch] = new Classes[MaxVal[table][bran

/* .... */

/* Clean up */

for (int table = 0;table < tables;table++)

for (int branch = 0;branch < branches;branch++)

delete[] Freq[table][branch];

}

--------8<--------

Thanks Dan for letting me know where the memory was consumed. I'll try to change everything to 1-d array and calculate indexes then. Yes I do need 4-dimensional array (the whole logic is quite complicated so I can't explain too much), I guess with converting this 4D array to 1D, then I won't have the problem of occupying extra memory then?

What do I do then? Please help.

Unless I'm mistaken, you've got a jagged array, which means that you'll need something like this:

--------8<--------

/*const*/ int tables = 13; // Not const

/*const*/ int branches = 2; // Not const

const int classes = 3;

struct Classes {

float score[classes]; /* I'm guessing this contains scores?! */

float operator[] (int index) {return score[index];}

};

int main()

{

/* Need to allocate */

int *MaxVal = new int[tables*branches];

/* Assign */

MaxVal[0*branches+0] = MaxVal[0*branches+1] = 8;

MaxVal[1*branches+0] = MaxVal[1*branches+1] = 52342;

// ...etc...

/* Allocate */

Classes* Freq[tables*branches];

for (int table = 0;table < tables;table++)

for (int branch = 0;branch < branches;branch++)

Freq[table*branches+branch

/* .... */

/* Clean up */

for (int table = 0;table < tables;table++)

for (int branch = 0;branch < branches;branch++)

delete[] Freq[table*branches+branch

delete[] MaxVal;

}

--------8<--------

(1) I needed to make the operator return a reference to make it a valid LHS for assignments

(2) My allocation was a bit drunk:

Classes** Freq = new Classes*[tables*branches];

This should work:

--------8<--------

/*const*/ int tables = 13; // Not const

/*const*/ int branches = 2; // Not const

const int classes = 3;

struct Classes {

float score[classes]; /* I'm guessing this contains scores?! */

float& operator[] (int index) {return score[index];}

};

int main()

{

/* Need to allocate */

int *MaxVal = new int[tables*branches];

/* Assign */

MaxVal[0*branches+0] = MaxVal[0*branches+1] = 8;

MaxVal[1*branches+0] = MaxVal[1*branches+1] = 52342;

// ...etc...

/* Allocate */

Classes** Freq = new Classes*[tables*branches];

for (int table = 0;table < tables;table++)

for (int branch = 0;branch < branches;branch++)

Freq[table*branches+branch

/* .... */

Freq[0*0+0][0][0] = 1;

/* Clean up */

for (int table = 0;table < tables;table++)

for (int branch = 0;branch < branches;branch++)

delete[] Freq[table*branches+branch

delete[] Freq;

delete[] MaxVal;

}

--------8<--------

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trialFreq[0][0][0][0] = 1;

... you should be able to use the following approach.

--------8<--------

/*const*/ int tables = 13; // Not const

/*const*/ int branches = 2; // Not const

const int classes = 3;

struct Classes {

float score[classes]; /* I'm guessing this contains scores?! */

float& operator[] (int index) {return score[index];}

};

class A4 {

Classes** Freq;

int tables,branches;

public:

A4(int tables,int branches,const int *MaxVal): tables(tables),branches(br

Freq = new Classes*[tables*branches];

for (int table = 0;table < tables;table++)

for (int branch = 0;branch < branches;branch++)

Freq[table*branches+branch

}

~A4() {

for (int table = 0;table < tables;table++)

for (int branch = 0;branch < branches;branch++)

delete[] Freq[table*branches+branch

delete[] Freq;

}

Classes** operator[] (int index) {

return &Freq[index*branches];

}

};

int main()

{

/* Need to allocate */

int *MaxVal = new int[tables*branches];

/* Assign */

MaxVal[0*branches+0] = MaxVal[0*branches+1] = 8;

MaxVal[1*branches+0] = MaxVal[1*branches+1] = 52342;

// ...etc...

/* Instance of Freq - note that this is now an instance of a class */

A4 Freq(tables,branches,MaxVa

/* This indexing works using two different operator overloads */

Freq[0][0][0][0] = 1;

delete[] MaxVal;

}

--------8<--------

C++

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Experts Exchange Solution brought to you by

Enjoy your complimentary solution view.

Get every solution instantly with premium.
Start your 7-day free trial.

Can you be serious about using a pointer to a pointer to a pointer to a pointer to a float?

The reason the table is taking up so much room is that for each float value, there are 24 bytes of pointers involved.

I suggest that you examine the needs of your program carefully. It is very rare to actually need a 4-dimensional array. A much more common situation would be a 2-D array of structures, but I can't really tell what your goal is from that code.

If you do actually need a 4-D array, then you can avoid all of the pointer-poiner-pointer-poi

float *pafTheFloats = new float[MAX_X * MAX_Y];

float GetValueFromArray( int x, int y )

{

float fRet= pafTheFloats[ (MAX_X*y) + c ];

return (fRet );

}

Similar logic for a 3-D-Array:

float *pafTheFloats = new float[MAX_X * MAX_Y * MAX_Z];

float GetValueFromArray( int x, int y, int z )

{

float fRet= pafTheFloats[ (MAX_X*MAX_Y*z) +(MAX_Y*x) +z ];

return (fRet );

}

A 4D array is so seldom needed that I'll not bother to illustrate it unless you can convince me you actually need to use one.

If you use a scheme like this, your memory allocation will exactly match what you expect: the total_number_of_floats * sizeof(float)

-- Dan