【问题标题】:Correct interpretation of dynamic 2D array allocation in CC中动态二维数组分配的正确解释
【发布时间】:2016-02-16 19:48:46
【问题描述】:

我无法正确解释在 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 的返回值的检查):

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 调用都有一个错字

【问题讨论】:

  • arr = calloc( Nrows , (sizeof arr)); 在这两个例子中都应该是arr = calloc(Nrows, sizeof *arr);
  • 错误的星数。这是一条经验法则:x = calloc(n, sizeof(*x))。如果您的代码与此模式不匹配,请用拇指戳键盘直到匹配为止。
  • 您的代码中没有二维数组。 指针不是数组。
  • @alk 谢谢,这是一个错字
  • OT:所有这些long ints 最好是size_ts 或至少是未签名的。

标签: c arrays malloc calloc


【解决方案1】:

假设 matix_d 是明确的。

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

数组第一级中的每个“位置”都会存储第二个内存区域中的位置。

存储和收集第二块内存区域的方法有点混乱。第一个 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;

这对您解释代码有帮助吗?

【讨论】:

  • 感谢您的回答。首先,你当然是错的sizeof。其次,听起来您推荐第一种方法(matrix_d),因为它更容易理解。 (有时,使用您理解的东西比使用您并不真正理解的东西更好,但在某些性能统计数据中似乎更好)。
猜你喜欢
  • 2018-09-01
  • 2021-02-03
  • 2015-09-17
  • 1970-01-01
  • 1970-01-01
  • 2015-02-10
  • 2016-03-15
  • 2013-11-14
  • 1970-01-01
相关资源
最近更新 更多