正确解释C中的动态二维数组分配

时间:2015-11-15 18:05:35

标签: c arrays malloc calloc

我有问题正确解释在C中动态分配2D数组的两种不同方式。

第一种方法是读取(为了便于阅读,我省略了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的返回值的检查):

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;

注释行显示我可能没有正确理解内存分配...特别是第二种方法在某种程度上让我感到困惑(但在这种意义上它似乎“更好”,它只需要2个calloc / malloc调用)

你们当中有人可能会指出我正确的解释吗?非常感谢!     }

编辑:两种方法的第一次calloc调用

都有拼写错误

1 个答案:

答案 0 :(得分:2)

假设matix_d已清除。

第二个函数创建两个内存区域。一个用于存储指向列的指针,另一个用于存储数据本身。

每个&#34;位置&#34;在数组的第一级中,存储第二个存储区中的位置。

存储和收集第二个存储区的方法有点令人困惑。首先分配arr [0]并使用* arr检索。这是一样的。

此外,当向指针添加1时,将使用指针指向的数据大小增加指针值。所以((double *)0)+ 1与((double *)sizeof(double))相同。

我认为最好使用指向第二个内存区域的本地指针,并在for循环中使用该指针。

其次,sizeof是错误的。你想要分配(cols *行)双打。使用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;

这有助于您解释代码吗?