【问题标题】:what is the better practice to allocate 2d array in C在C中分配二维数组的更好做法是什么
【发布时间】:2015-05-19 14:16:25
【问题描述】:

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

  1. 在 C99 中使用 VLA。
size_t rows, cols;
int (*arr)[cols] = malloc(sizeof *arr * rows);
if (arr)
{
  // do something here

  free(arr);
}
  1. 使用指向指针的指针
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);
}

我想知道这两者中哪一个更适合练习,或者还有其他更好的解决方案?对我来说,第一个更简洁,但是因为二维数组会经常被用作参数传递给函数,所以看起来第二个更好。我不是编程专家,所以我想听听您的意见。谢谢。

【问题讨论】:

  • 要考虑的一个因素是您是否要将这些二维数组传递给任何现有的 API。例如。如果现有 API 需要 int **,那么使用方法 (1) 将是愚蠢的。
  • 你的意思是人们使用第二个比第一个更频繁?@Paul R
  • @PaulR 您可以使用方法 1 并设置一个指针数组以传递给这些 API 函数。当然,如果连续内存对您的应用程序有利。
  • 方法2其实编码错误。我猜你打算分配一个连续的块,然后分配指向该块每一行的指针。但是使用方法 1 然后继续 int *row_pointers[rows]; 仍然会更简单
  • @wallen 语句中使用的数据在哪里 *data = (int *) malloc(nbytes);宣布?!

标签: c arrays 2d


【解决方案1】:

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

主要问题是int (*)[N]int ** 类型不兼容,简单地将一个转换为另一个不会满足您的要求。如果您使用的 API 需要 int **,那么您需要使用第二种方法。

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

void func( size_t cols, size_t rows, int (*arr)[cols] )

可能比阅读更尴尬

void func ( int **arr, size_t rows, size_t cols )

如果您不依赖任何外部 API 并且可以完全控制您的实现方式,请使用第一种方法。它在代码方面更干净,它保证了连续的内存,并且更易于管理。权衡是一些稍微粗糙的语法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-05-11
    • 1970-01-01
    • 2011-02-10
    • 2020-08-28
    • 2018-10-11
    • 2013-11-14
    相关资源
    最近更新 更多