在C中分配2d数组的更好的做法是什么

时间:2015-05-19 14:16:25

标签: c arrays 2d

我正在为MD模拟编写一个程序,其中我需要使用动态分配的2D数组。出于性能原因,我希望内存中的2D阵列是一个连续的块。我知道有两种方法可以做到这一点

  1. 在C99中使用VLA。
  2. size_t rows, cols;
    int (*arr)[cols] = malloc(sizeof *arr * rows);
    if (arr)
    {
      // do something here
    
      free(arr);
    }
    
    1. 使用指针指针
    2. int **create(int **arr, int rows, int cols)
      {
        int nbytes = sizeof(int) * rows * cols;
        int *data = (int *) malloc(nbytes);
        nbytes = sizeof(int *) * rows;
        arr = (int **)malloc(nbytes);
        int n = 0;
        for (int i=0; i <rows; i++){
          arr[i] = &data[n];
          n += cols;
          }
        retrun arr;
       }
      void destroy(int **arr)
      {
        if (arr == NULL) return;
        free(arr[0]);
        free(arr);
      }
      

      我想知道哪两个更适合练习,还是有另一个更好的解决方案?对我来说,第一个是更简洁,但因为2d数组将被用作参数传递非常频繁,所以看起来第二个更好。我不是编程方面的专家,所以我想听听你的意见。感谢。

1 个答案:

答案 0 :(得分:0)

只有第一种方法可以保证在单个连续的块中分配内存。第二种方法不保证行在内存中相邻(很可能,它们不会)。

主要障碍是int (*)[N]int **类型不兼容,只需将其中一个投射到另一个就不会做你想要的。如果您使用的是期望int **的API,那么您需要使用第二种方法。

至于将每个作为参数传递,没有实际的性能差异;它们都是指针类型。唯一真正的问题是

void func( size_t cols, size_t rows, int (*arr)[cols] )
阅读可能比

更难尴尬
void func ( int **arr, size_t rows, size_t cols )

如果您不依赖任何外部API并完全控制如何实现,请使用第一种方法。它在代码方面更加清晰,它保证了连续的内存,并且更易于管理。权衡是一些非常粗略的语法。