Thread: 3d array allocation

  1. #1
    Registered User C_ntua's Avatar
    Join Date
    Jun 2008
    Posts
    1,853

    3d array allocation

    Would this work?
    Code:
    int (*p)[x][y] = malloc(z * sizeof(*p));
    If I understand correctly, p is a pointer to a 2D array and sizeof(*p) will be sizeof(int)*x*y?

  2. #2
    Banned master5001's Avatar
    Join Date
    Aug 2001
    Location
    Visalia, CA, USA
    Posts
    3,685
    You are correct... but you tell me if z is appropriately sized?

  3. #3
    Banned master5001's Avatar
    Join Date
    Aug 2001
    Location
    Visalia, CA, USA
    Posts
    3,685
    Wait... I just noticed your title. Let me ask you this, is this a 3d array?

  4. #4
    Registered User C_ntua's Avatar
    Join Date
    Jun 2008
    Posts
    1,853
    I suppose. I mean since you have a pointer and the appropriate space you could do:
    Code:
    for (int i=0; i<z; ++i)
       for (int j=0; j<y; ++j)
          for (int k=0; k<x; ++k)
              printf("%d", p[k][y][i]; //or p[i][y][k]?

  5. #5
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    The loop limits would be z, x, y
    The subscript would be [i][j][k]
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  6. #6
    Registered User C_ntua's Avatar
    Join Date
    Jun 2008
    Posts
    1,853
    Quote Originally Posted by Salem View Post
    The loop limits would be z, x, y
    The subscript would be [i][j][k]
    Yeah, typed it wrong. But to get this straight.... would my first code malloc() a 3rd array?

  7. #7
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Not on it's own, no.

    It allocates ONE array element of z dimension. you need x * y of them, each one installed in the respective [x][y] pointer.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  8. #8
    Registered User C_ntua's Avatar
    Join Date
    Jun 2008
    Posts
    1,853
    Code:
    int (*p)[x][y] = malloc(z * sizeof(*p));
    So how much space does this allocates?
    Since p is a pointer to a 2D array doesn't that mean that sizeof(*p) is the size of the 2D array, thus x*y*sizeof(int) ?
    If that is true, then the above will allocate z*y*x*sizeof(int) space, thus space for a 3D array.

    I could do of course:
    Code:
    int ***p = malloc(z * sizeof(*p));
    for (...) {
       p[...] = malloc(...)
       for (...)
           p[...][...] = malloc(...)
    }
    and allocate a 3d array, but I am just wondering if the one line code would work, since it is simpler and guarantees a contiguous space of memory.

    If it won't work, I would like to know what would happen. The pointer to a 2D array syntax is not that clear in C

  9. #9
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    A 3D that uses dynamic allocation will need to allocate one chunk of memory for each [x][y] location, so even if you avoid doing the first two levels of allocation, you still need to use a loop to fill in the bottom layer of the pointers.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  10. #10
    Registered User C_ntua's Avatar
    Join Date
    Jun 2008
    Posts
    1,853
    Lets say you allocate one array. You would do:
    Code:
    int *p = malloc(z*sizeof(int));
    So you have this:
    p--> M1
    The pointer points to one int, so you just allocate z int and have an array.
    p--> M1 ..... Mz

    If you had though (*p)[3][3] wouldn't that meant that you have this:
    p--> M1 M2 M3 M4 M5 M6 M7 M8 M9
    So if you do what I posted you should have z times that.

    Maybe I am not understanding the (*)[][] syntax correctly?

    So you are saying that my line would be the first line of code to allocate and I would need a double loop to fill the array?

  11. #11
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    It's not about the amount of data you allocate, but rather how it is distributed in the array.

    To make things simpler, let's just use a 2D array:
    Code:
    int (*p)[3];
    
    p[0] = malloc(3 * sizeof(int));
    Now, you have a 2D array, but only one set of second level data, p[0][0..2] is available.

    To make that a proper 2D array, you would need to do:
    Code:
    for(i = 0; i < 3; i++)
       p[i] = malloc(3 * sizeof(int));
    Likewise, you need to allocate x * y blocks of z elements to make a 3D array, since each pointer p[x][y] is an individual pointer, and thus needs to point to the z elements it represents.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  12. #12
    Registered User C_ntua's Avatar
    Join Date
    Jun 2008
    Posts
    1,853
    Yes, but if you do this:
    Code:
    int (*p)[3];
    p = malloc(3 * sizeof(int[3]);
    which I assume is equivalent with this:
    Code:
    int (*p)[3];
    p = malloc(3 * sizeof(*p);
    The thing is that I can understand how pointers work. But int*** p is no the same as int p[][x][y]. How the second is implemented is not really clear. But I understand that if you do this:
    Code:
    int a[2][2][2];
    int (*p)[2][2] = a;
    p[0][0][1] = 2;
    then p points to a and you can use the indexes correctly.
    So you point p to a chunk of memory that has 8*sizeof(int).
    Instead of that, can't you dynamically allocate that piece of memory?

    I should use this example which is more to my point, for a 2D array:
    Code:
    char (*p)[10] = malloc(100);
    So you have a pointer that points to a chunk of 100byts. Shouldn't the indexes work as you expect?

  13. #13
    Registered User C_ntua's Avatar
    Join Date
    Jun 2008
    Posts
    1,853
    Am I just missing an index here? I mean would this work?
    Code:
    char (*p)[10][10] = malloc(100);
    And use it like:
    Code:
    p[0][0] = '1'; p[1][0] = '2'; etc etc

  14. #14
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > It allocates ONE array element of z dimension. you need x * y of them, each one installed in the respective [x][y] pointer.
    But that's what the sizeof(*p) in the original post tells you surely.
    It should give you the same result as sizeof( int[x][y] ).

    IMO, int (*p)[x][y] = malloc(z * sizeof(*p)); does what you want, so long as x and y are compile-time constants.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  15. #15
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > It allocates ONE array element of z dimension. you need x * y of them, each one installed in the respective [x][y] pointer.
    But that's what the sizeof(*p) in the original post tells you surely.
    It should give you the same result as sizeof( int[x][y] ).

    IMO, int (*p)[x][y] = malloc(z * sizeof(*p)); does what you want, so long as x and y are compile-time constants.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Dynamic allocation for array of pointers to char
    By bivhitscar in forum C Programming
    Replies: 7
    Last Post: 05-20-2006, 07:04 AM
  2. Quick question about SIGSEGV
    By Cikotic in forum C Programming
    Replies: 30
    Last Post: 07-01-2004, 07:48 PM
  3. Merge sort please
    By vasanth in forum C Programming
    Replies: 2
    Last Post: 11-09-2003, 12:09 PM
  4. 3D array
    By GSLR in forum C Programming
    Replies: 2
    Last Post: 05-12-2002, 04:00 PM
  5. 3D Array
    By Alextrons in forum Windows Programming
    Replies: 4
    Last Post: 01-11-2002, 01:39 AM