C 中动态二维数组分配的正确解释
Correct interpretation of dynamic 2D array allocation in C
我无法正确解释在 C 中动态分配二维数组的两种不同方式。
第一种方法读取(为了便于阅读,我省略了 if(arr==NULL)
检查):
double** matrix_d( long int Nrows, long int Ncols ) {
long int ii;
double** arr;
// allocate pointer to rows
arr = calloc( Nrows , (sizeof *arr));
for( ii=0 ; ii < Nrows; ii++) {
// allocate pointer to each column (?)
arr[ii] = calloc( Ncols , (sizeof **arr) );
}
return arr;
}
第二种方法读取(同样,省略了对 calloc 的 return 值的检查):
double** matrix_d2( long int Nrows, long int Ncols ) {
long int ii;
double** arr;
// allocate pointers to rows
arr = calloc( Nrows , (sizeof *arr) );
// allocate rows (?)
arr[0] = calloc( Nrows*Ncols, (sizeof arr) );
// set pointers to rows (?)
for( ii=0 ; ii < Nrows; ii++)
arr[ii] = (*arr + Ncols*ii);
return arr;
评论行可能表明我缺乏对内存分配的正确理解......尤其是第二种方法让我有些困惑(但似乎 "better" 在这个意义上它只需要 2 calloc/malloc 来电)。
你们中的哪位能指出我正确的解释吗?那将不胜感激!
}
编辑:两种方法的第一个 calloc 调用都存在拼写错误
假设 matix_d 是清楚的。
第二个函数创建两个内存区域。一种用于存储指向列的指针,另一种用于保存数据本身。
第一层数组的每"position"存储第二个内存区域中的一个位置。
内存第二区的存储和收集方法有点乱。首先 arr[0] 被赋值并用 *arr 检索。哪个是一样的
此外,当指针加 1 时,指针的值会随着指针指向的数据的大小而增加。所以 ((double*)0) + 1 等同于 ((double*)sizeof(double)).
我认为最好使用指向第二个内存区域的本地指针并在 for 循环中使用该指针。
其次,sizeof不对。你想分配 (cols * rows) 双打。使用 sizeof(**arr) 或仅使用 sizeof(double).
double** matrix_d2( long int Nrows, long int Ncols ) {
long int ii;
double* data;
double** arr;
// allocate pointers to rows
arr = calloc( Nrows , (sizeof arr) );
// allocate data rows * cols
data = calloc( Nrows*Ncols, (sizeof **arr) );
// set pointers to rows
for( ii=0 ; ii < Nrows; ii++)
arr[ii] = (data + (Ncols*ii));
return arr;
这对您理解代码有帮助吗?
我无法正确解释在 C 中动态分配二维数组的两种不同方式。
第一种方法读取(为了便于阅读,我省略了 if(arr==NULL)
检查):
double** matrix_d( long int Nrows, long int Ncols ) {
long int ii;
double** arr;
// allocate pointer to rows
arr = calloc( Nrows , (sizeof *arr));
for( ii=0 ; ii < Nrows; ii++) {
// allocate pointer to each column (?)
arr[ii] = calloc( Ncols , (sizeof **arr) );
}
return arr;
}
第二种方法读取(同样,省略了对 calloc 的 return 值的检查):
double** matrix_d2( long int Nrows, long int Ncols ) {
long int ii;
double** arr;
// allocate pointers to rows
arr = calloc( Nrows , (sizeof *arr) );
// allocate rows (?)
arr[0] = calloc( Nrows*Ncols, (sizeof arr) );
// set pointers to rows (?)
for( ii=0 ; ii < Nrows; ii++)
arr[ii] = (*arr + Ncols*ii);
return arr;
评论行可能表明我缺乏对内存分配的正确理解......尤其是第二种方法让我有些困惑(但似乎 "better" 在这个意义上它只需要 2 calloc/malloc 来电)。
你们中的哪位能指出我正确的解释吗?那将不胜感激! }
编辑:两种方法的第一个 calloc 调用都存在拼写错误
假设 matix_d 是清楚的。
第二个函数创建两个内存区域。一种用于存储指向列的指针,另一种用于保存数据本身。
第一层数组的每"position"存储第二个内存区域中的一个位置。
内存第二区的存储和收集方法有点乱。首先 arr[0] 被赋值并用 *arr 检索。哪个是一样的
此外,当指针加 1 时,指针的值会随着指针指向的数据的大小而增加。所以 ((double*)0) + 1 等同于 ((double*)sizeof(double)).
我认为最好使用指向第二个内存区域的本地指针并在 for 循环中使用该指针。
其次,sizeof不对。你想分配 (cols * rows) 双打。使用 sizeof(**arr) 或仅使用 sizeof(double).
double** matrix_d2( long int Nrows, long int Ncols ) {
long int ii;
double* data;
double** arr;
// allocate pointers to rows
arr = calloc( Nrows , (sizeof arr) );
// allocate data rows * cols
data = calloc( Nrows*Ncols, (sizeof **arr) );
// set pointers to rows
for( ii=0 ; ii < Nrows; ii++)
arr[ii] = (data + (Ncols*ii));
return arr;
这对您理解代码有帮助吗?