我正在为MD模拟编写一个程序,其中我需要使用动态分配的2D数组。出于性能原因,我希望内存中的2D阵列是一个连续的块。我知道有两种方法可以做到这一点
size_t rows, cols;
int (*arr)[cols] = malloc(sizeof *arr * rows);
if (arr)
{
// do something here
free(arr);
}
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数组将被用作参数传递非常频繁,所以看起来第二个更好。我不是编程方面的专家,所以我想听听你的意见。感谢。
答案 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并完全控制如何实现,请使用第一种方法。它在代码方面更加清晰,它保证了连续的内存,并且更易于管理。权衡是一些非常粗略的语法。