CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 25
  1. #1
    Join Date
    Oct 2010
    Posts
    25

    3D array memory allocation dimensions

    Hello,

    I am using this piece of code for allocating 3D array in memory by my dimensions HEIGHT, WIDTH, DEPTH, which are variables.

    p2DArray = new double**[HEIGHT];
    for (int i = 0; i < HEIGHT; ++i) {
    p2DArray[i] = new double*[WIDTH];

    for (int j = 0; j < WIDTH; ++j)
    p2DArray[i][j] = new double[DEPTH];
    }

    My problem is this: When i have for example HEIGHT = 512, WIDTH = 512 and DEPTH = 2 my 3D allocated array has right dimension in HEIGHT and WIDTH but DEPTH dimensions are not 2, but its larger.

    For example when I want to read from p2DArray[511][511][845646] it doesnt say me, that I am out of dimensions (with [845646] in DEPTH), but it will give me random number value. When I want to read on position for example p2DArray[518][511][0] it will say me, that I am out of dimension because of HEIGHT size.

    Could you please tell me, why this piece of code allocates 3D array right in HEIGHT and WIDTH dimension, but false in DEPTH (it allocates a lot of bigger in DEPT dimension, than I would like)?

    THANKS FOR ANY HELP!

  2. #2
    Join Date
    Apr 1999
    Posts
    27,449

    Re: 3D array memory allocation dimensions

    Quote Originally Posted by Kositch View Post
    Hello,

    I am using this piece of code for allocating 3D array in memory by my dimensions HEIGHT, WIDTH, DEPTH, which are variables.

    p2DArray = new double**[HEIGHT];
    for (int i = 0; i < HEIGHT; ++i) {
    p2DArray[i] = new double*[WIDTH];

    for (int j = 0; j < WIDTH; ++j)
    p2DArray[i][j] = new double[DEPTH];
    }

    My problem is this: When i have for example HEIGHT = 512, WIDTH = 512 and DEPTH = 2 my 3D allocated array has right dimension in HEIGHT and WIDTH but DEPTH dimensions are not 2, but its larger.
    Show us a complete program that duplicates the error, not just a piece of code. We can't see into your computer, so there is no way we can verify your claims.

    There is nothing wrong with that code (except that it is extremely inefficient).

    Regards,

    Paul McKenzie

  3. #3
    Join Date
    Oct 2010
    Posts
    25

    Re: 3D array memory allocation dimensions

    Quote Originally Posted by Paul McKenzie View Post
    Show us a complete program that duplicates the error, not just a piece of code. We can't see into your computer, so there is no way we can verify your claims.

    There is nothing wrong with that code (except that it is extremely inefficient).

    Regards,

    Paul McKenzie
    OK, thanks for reply, here is the code example with my problem:

    short int ***test;

    int HEIGHT = 10;
    int WIDTH = 20;
    int DEPTH = 3;

    test = new short int**[HEIGHT]; //allocating memory for arry of size 10 x 20 x 3
    for (int x = 0; x < HEIGHT; ++x) {
    test[x] = new short int*[WIDTH];
    for (int y = 0; y < WIDTH; ++y)
    test[x][y] = new short int[DEPTH];
    }

    for (int z = 0; z < DEPTH; z++) //filling it with ones
    {
    for (int y = 0; y < WIDTH; y++)
    {
    for (int x = 0; x < HEIGHT; x++)
    {
    test[x][y][z] = 1;
    }
    }
    }

    cout << test[5][15][2]; //it will write number one, its ok
    cout << test[5][15][5]; //it should say, that i am off the array size with number 5 in depth dimension (program should throw exception), but it will write some random number -21598 and doesnt throw any exception, that i am looking out of allocated memory

  4. #4
    Join Date
    Apr 1999
    Posts
    27,449

    Re: 3D array memory allocation dimensions

    Quote Originally Posted by Kositch View Post
    cout << test[5][15][5]; //it should say, that i am off the array size with number 5 in depth dimension (program should throw exception),
    Where did you get that erroneous information from?
    but it will write some random number -21598 and doesnt throw any exception, that i am looking out of allocated memory
    Welcome to the world of C++ programming.

    When you make a mistake such as writing outside the boundaries of an array in a C++ program, there is nothing that guarantees how your program will behave. The program may throw an exception, or it may work without anything happening, or may throw an exception when run on your machine but run without anything happening on another machine, plain old crash without an exception, etc.

    C++ is not Java or C#, or some other computer language that has these checks at runtime and automatically will inform you of a problem.

    Regards,

    Paul McKenzie
    Last edited by Paul McKenzie; October 10th, 2010 at 03:23 PM.

  5. #5
    Join Date
    Oct 2010
    Posts
    25

    Re: 3D array memory allocation dimensions

    Quote Originally Posted by Paul McKenzie View Post
    Where did you get that erroneous information from?Welcome to the world of C++ programming.

    When you make a mistake such as writing outside the boundaries of an array in a C++ program, there is nothing that guarantees how your program will behave. The program may throw an exception, or it may work without anything happening, or may throw an exception when run on your machine but run without anything happening on another machine, plain old crash without an exception, etc.

    C++ is not Java or C#, or some other computer language that has these checks at runtime and automatically will inform you of a problem.

    Regards,

    Paul McKenzie
    Thanks for explanation, but why i am making memory allocation, when i can read from array also out of its boundaries?

    So my code is right and it allocates only memory that i need?

  6. #6
    Join Date
    Jul 2005
    Location
    Netherlands
    Posts
    2,042

    Re: 3D array memory allocation dimensions

    Quote Originally Posted by Kositch View Post
    why i am making memory allocation, when i can read from array also out of its boundaries?
    I assume because nobody taught you proper C++. There is really no need to manually handle dynamic arrays like you do. If you would use a std::vector<std::vector<std::vector<short> > > you would get the same effect as what your code does, but without having to manage the memory yourself. Also, you can use the vector's at member function to enforce bounds checking.

    An even better solution might be to use boost::multi_array, if you are willing to learn how to use it.
    Cheers, D Drmmr

    Please put [code][/code] tags around your code to preserve indentation and make it more readable.

    As long as man ascribes to himself what is merely a posibility, he will not work for the attainment of it. - P. D. Ouspensky

  7. #7
    Join Date
    Apr 1999
    Posts
    27,449

    Re: 3D array memory allocation dimensions

    Quote Originally Posted by Kositch View Post
    Thanks for explanation, but why i am making memory allocation, when i can read from array also out of its boundaries?
    I don't quite understand your question.

    Reading and writing beyond the boundaries of an array leaves the behaviour of the program undefined. You're asking "how come I can do this in C++", and I answered already -- C++ does not check for array accesses being out of bounds.
    So my code is right and it allocates only memory that i need?
    There are container classes, as mentioned previously, where you do not need to handle the memory yourself. For example, std::vector.

    As far as your current code goes, there are much better ways of handling the memory. Please take a look:
    Code:
    double***Create3DArray(int height, int width, int depth)
    {
    	double ***p3DArray = new double**[height];
    	double **data1 = new double*[height * width];
    	double *data2 = new double[ height * width * depth];
    
    	for (int i = 0; i < height; ++i, data1 += width) 
    	{
    		p3DArray[i] = data1;
    		for (int j = 0; j < width; ++j, data2 += depth)
    			p3DArray[i][j] = data2;
    	}
    	return p3DArray;
    }
    
    void Free3DArray(double ***array3d)
    {
        // you fill this in to release the memory
    }
    
    int main(int argc, _TCHAR* argv[])
    {
    	double ***myArray = Create3DArray(512, 512, 2);
    	myArray[0][2][4] = 59; // for example
    	Free3DArray(myArray);
    	return 0;
    }
    Note that there are only 3 calls to "new", regardless of the width, height, and depth. The trick is to allocate all of the memory for the array, and then point the pointers into the pool of memory correctly. Similarly, it only takes 3 calls to "delete[]". I didn't show this to you, since this looks like a homework assignment.

    As to your current code, it makes height*width + 1 calls to "new". That can seriously fragment the heap as well as slow down the creation of the array.

    Imagine if the width and height were 500. You would be making 250,001 calls to "new[]", and to release the memory, you would be making 250,001 calls to delete[]. That is way too many times to be calling the allocator. But with the code I posted, it will still do just 3 calls to "new[]".

    Regards,

    Paul McKenzie

  8. #8
    Join Date
    Oct 2010
    Posts
    25

    Re: 3D array memory allocation dimensions

    Quote Originally Posted by Paul McKenzie View Post
    I don't quite understand your question.

    Reading and writing beyond the boundaries of an array leaves the behaviour of the program undefined. You're asking "how come I can do this in C++", and I answered already -- C++ does not check for array accesses being out of bounds.
    There are container classes, as mentioned previously, where you do not need to handle the memory yourself. For example, std::vector.

    As far as your current code goes, there are much better ways of handling the memory. Please take a look:
    Code:
    double***Create3DArray(int height, int width, int depth)
    {
    	double ***p3DArray = new double**[height];
    	double **data1 = new double*[height * width];
    	double *data2 = new double[ height * width * depth];
    
    	for (int i = 0; i < height; ++i, data1 += width) 
    	{
    		p3DArray[i] = data1;
    		for (int j = 0; j < width; ++j, data2 += depth)
    			p3DArray[i][j] = data2;
    	}
    	return p3DArray;
    }
    
    void Free3DArray(double ***array3d)
    {
        // you fill this in to release the memory
    }
    
    int main(int argc, _TCHAR* argv[])
    {
    	double ***myArray = Create3DArray(512, 512, 2);
    	myArray[0][2][4] = 59; // for example
    	Free3DArray(myArray);
    	return 0;
    }
    Note that there are only 3 calls to "new", regardless of the width, height, and depth. The trick is to allocate all of the memory for the array, and then point the pointers into the pool of memory correctly. Similarly, it only takes 3 calls to "delete[]". I didn't show this to you, since this looks like a homework assignment.

    As to your current code, it makes height*width + 1 calls to "new". That can seriously fragment the heap as well as slow down the creation of the array.

    Imagine if the width and height were 500. You would be making 250,001 calls to "new[]", and to release the memory, you would be making 250,001 calls to delete[]. That is way too many times to be calling the allocator. But with the code I posted, it will still do just 3 calls to "new[]".

    Regards,

    Paul McKenzie
    Thanks a lot, this look better then my.

    The delete part of the code will be like this?:

    Code:
    	delete []  array3d**[height];
    	delete []  array3d*[height * width];
    	delete []  array3d[ height * width * depth];

  9. #9
    Join Date
    Apr 1999
    Posts
    27,449

    Re: 3D array memory allocation dimensions

    Quote Originally Posted by Kositch View Post
    Thanks a lot, this look better then my.

    The delete part of the code will be like this?:

    Code:
    	delete []  array3d**[height];
    	delete []  array3d*[height * width];
    	delete []  array3d[ height * width * depth];
    Actually no, but you have the right idea. The first thing is that you delete in reverse order that the data was allocated.

    So you delete the pool of memory first (data2). Since the start of the pool is at array[0][0], you delete this. Then you delete where data1 starts. This is at array[0]. Then last, you delete array.

    Regards,

    Paul McKenzie

  10. #10
    Join Date
    Oct 2010
    Posts
    25

    Re: 3D array memory allocation dimensions

    So like that?:

    Code:
    delete [] array3d[0][0]
    delete [] array3d[0]
    delete [] array3d

    I hope, it's right now :-) There will be needed no for cycles?
    Last edited by Kositch; October 11th, 2010 at 02:03 AM.

  11. #11
    Join Date
    Jun 2009
    Location
    France
    Posts
    2,513

    Re: 3D array memory allocation dimensions

    Quote Originally Posted by Kositch View Post
    So like that?:

    Code:
    delete [] array3d[0][0]
    delete [] array3d[0]
    delete [] array3d
    I hope, it's right now :-) There will be needed no for cycles?
    Nope, you are still missing a ton of deletes. The syntax is;
    Code:
    delete [] pointer;
    the keyword is "delete []", which will delete the array allocated at pointer. Note that at no point in time do you specify the size of the object to be deleted. You need one delete per allocation, so in your case:

    Code:
    for (int x = 0; x < HEIGHT; ++x)
    {
        for (int y = 0; y < WIDTH; ++y)
        {
            delete [] test[x][y];;
        }
        delete [] test[x];
    }
    delete [] test;
    Just delete in the oposite order that you allocated.

    EDIT: Arrays are "fun" for learning, But I highly recommend you learn to use vectors. Understanding how an array works is important, but learning to use vectors correctly is even more important.
    Last edited by monarch_dodra; October 11th, 2010 at 03:20 AM.
    Is your question related to IO?
    Read this C++ FAQ article at parashift by Marshall Cline. In particular points 1-6.
    It will explain how to correctly deal with IO, how to validate input, and why you shouldn't count on "while(!in.eof())". And it always makes for excellent reading.

  12. #12
    Join Date
    Jul 2010
    Posts
    94

    Re: 3D array memory allocation dimensions

    Fun about what ?
    It's more dangerous to use than vector
    But it looks neat: only new then delete everything seems fine after all

  13. #13
    Join Date
    Apr 1999
    Posts
    27,449

    Re: 3D array memory allocation dimensions

    Quote Originally Posted by monarch_dodra View Post
    Nope, you are still missing a ton of deletes.
    For the code I posted, the set of three deletes are correct. For the original OP's code, your code is correct.

    Regards,

    Paul McKenzie

  14. #14
    Join Date
    Jun 2009
    Location
    France
    Posts
    2,513

    Re: 3D array memory allocation dimensions

    Quote Originally Posted by Paul McKenzie View Post
    For the code I posted, the set of three deletes are correct. For the original OP's code, your code is correct.

    Regards,

    Paul McKenzie
    Whoops. Sorry about that. Hadn't read your post in detail.
    Is your question related to IO?
    Read this C++ FAQ article at parashift by Marshall Cline. In particular points 1-6.
    It will explain how to correctly deal with IO, how to validate input, and why you shouldn't count on "while(!in.eof())". And it always makes for excellent reading.

  15. #15
    Join Date
    Oct 2010
    Posts
    25

    Re: 3D array memory allocation dimensions

    Quote Originally Posted by Paul McKenzie View Post
    For the code I posted, the set of three deletes are correct. For the original OP's code, your code is correct.

    Regards,

    Paul McKenzie
    Paul, so my second try of deleting array is now right (code is above)?

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured