dynamic allocation/deallocation of 2D & 3D arrays

后端 未结 4 2136
离开以前
离开以前 2020-12-01 05:10

I know about algorithms to allocate/deallocate a 2D array dynamically, however I\'m not too sure about the same for 3D arrays.
Using this knowledge and a bit of symmetry

相关标签:
4条回答
  • 2020-12-01 05:17

    This is a version of the idea in the question but using only one malloc, inspired by the other answers. It allows intuitive use of the square brackets and easy cleaning. I hope it does not make any compiler implementation specific assumption.

    int main(int argc, char *argv[])
    {
      int **array, i, j;
      array = allocate2d(3, 4);
      for (i = 0; i < 3; i++)
      {
        for (j = 0; j < 4; j++)
        {
          array[i][j] = j + i + 1;
        }
      }
      for (i = 0; i < 3; i++)
      {
        for (j = 0; j < 4; j++)
        {
          printf("array[%d][%d] = %d\n", i, j, array[i][j]);
        }
      }
      free(array);
      return EXIT_SUCCESS;
    }
    
    int **allocate2d(int x, int y)
    {
      int i;
      int **array = malloc(sizeof(int *) * x + sizeof(int) * x * y);
      for (i = 0; i < x; i++)
      {
        array[i] = ((int *)(array + x)) + y * i;
      }
      return array;
    }
    
    0 讨论(0)
  • 2020-12-01 05:25

    You can see the below code:

    #include <stdio.h>
    #include <stdlib.h>
    
    void main()
    {
        //  Array 3 Dimensions
        int x = 4, y = 5, z = 6;
    
        //  Array Iterators
        int i, j, k;
    
        //  Allocate 3D Array
        int *allElements = malloc(x * y * z * sizeof(int));
        int ***array3D = malloc(x * sizeof(int **));
    
        for(i = 0; i < x; i++)
        {
            array3D[i] = malloc(y * sizeof(int *));
    
            for(j = 0; j < y; j++)
            {
                array3D[i][j] = allElements + (i * y * z) + (j * z);
            }
        }
    
        //  Access array elements
        for(i = 0; i < x; i++)
        {
            printf("%d\n", i);
    
            for(j = 0; j < y; j++)
            {
                printf("\n");
    
                for(k = 0; k < z; k++)
                {
                    array3D[i][j][k] = (i * y * z) + (j * z) + k;
                    printf("\t%d", array3D[i][j][k]);
                }
            }
    
            printf("\n\n");
        }
    
        //  Deallocate 3D array
        free(allElements);
        for(i = 0; i < x; i++)
        {
            free(array3D[i]);
        }
        free (array3D);
    }
    

    For more details see this link 3d array

    0 讨论(0)
  • 2020-12-01 05:38

    You can also allocate one array and compute individual indices. This requires fewer allocator calls and results in both less fragmentation and better cache use.

    typedef struct {
      int a;
      int b;
      int* data;
    } Int2d;
    
    Int2d arr2d = { 2, 3 };
    arr2d.data = malloc(arr2d.a * arr2d.b * sizeof *arr2d.data);
    

    Now arr2d[r][c] becomes arr2d.data[r * arr2d.b + c]. Deallocation is a single free() away. As a bonus you're sure to always keep your dynamic array sizes with you.

    Extrapolating to 3d:

    typedef struct {
      int a;
      int b;
      int c;
      int* data;
    } Int3d;
    
    Int3d arr3d = { 2, 3, 4 };
    arr3d.data = malloc(arr3d.a * arr3d.b * arr3d.c * sizeof *arr3d.data);
    
    //arr3d[r][c][d]
    // becomes:
    arr3d.data[r * (arr3d.b * arr3d.c) + c * arr3d.c + d];
    

    You should encapsulate these index operations (and the (de-)allocations for that matter) in a separate function or macro.

    (The names for r, c, and d could be better—I was going for row, column, and depth. While a, b, and c are the limits of their corresponding dimensions, you might prefer something like n1, n2, n3 there, or even use an array for them.)

    0 讨论(0)
  • 2020-12-01 05:43

    arr3d should be a triple pointer and not just an int. Otherwise looks OK:

    void deallocate3D(int*** arr3D,int l,int m)
    {
        int i,j;
    
        for(i=0;i<l;i++)
        {
            for(int j=0;j<m;j++)
            {
                    free(arr3D[i][j]);
            }
            free(arr3D[i]);
        }
        free(arr3D);
    }
    

    arr3D is a pointer-to-pointer-to-pointer, so arr3D[i] is a pointer-to-pointer and arr3D[i][j] just a pointer. It's correct to release the lowest dimension in a loop first, and then climb up the dimensions until arr3D itself is released.

    Also it's more idiomatic to give malloc the sizeof of the pointed type implicitly. Instead of:

      arr3D[i] = (int**)malloc(m * sizeof(int*));
    

    Make it:

      arr3D[i] = (int**)malloc(m * sizeof(*arr3D[i]));
    

    And yes, such dynamically allocated multi-dimensional arrays can be accessed just as statically allocated multi-dimensional arrays.

    0 讨论(0)
提交回复
热议问题