差异b/w在1行或逐行中将内存分配给2D阵列

use*_*982 5 c malloc multidimensional-array

在这两种情况下,访问数组或内存分配会产生什么影响:

1.

    int **arr;
    arr = malloc( sizeof(int) * row * column );
Run Code Online (Sandbox Code Playgroud)

2.

    int **arr;
    arr = malloc( sizeof(*arr) * row);
    for(i=0; i<row; i++)
        arr[i] = malloc( sizeof( **arr) * column));
Run Code Online (Sandbox Code Playgroud)

AnT*_*AnT 6

  • 首先,"影响"是你的第一种方法被打破.它不会通过int **指针工作.

    为了在第一个方法中尝试在一个镜头中分配2D数组时,实际上必须分配一个足够大小的一维数组

    int *arr = malloc( row * column * sizeof *arr );
    // Note: `int *`, not `int **`
    
    Run Code Online (Sandbox Code Playgroud)

    并通过手动索引重新计算来执行访问,例如,而不是arr[i][j]您必须这样做arr[i * column + j].

    尝试将分配的指针存储在int **arr然后访问您的数组,这arr[i][j]将导致崩溃.

  • 其次,你的第二种方法还可以.只是在第二种方法中,您并不需要通过多次独立malloc调用来分配第二级内存.您可以一次性分配整个二级存储器

    int **arr = malloc( row  * sizeof *arr );
    int *arr_data = malloc( row * column * sizeof *arr_data );
    
    Run Code Online (Sandbox Code Playgroud)

    然后只在行之间分配预先分配的第二级内存

    for (i = 0; i < row; i++)
      arr[i] = arr_data + i * column;
    
    Run Code Online (Sandbox Code Playgroud)

    (当然,如果你愿意,你可以独立分配行.它也可以工作.我想一次性分配它们的原因是为了更好地说明第一种和第二种方法之间的相似性,如下所述.)

现在,通过查看这两种方法,您可以很容易地看到它们基本上都做同样的事情.唯一的区别是,在第一种方法中,您可以通过arr + i * column每次计算(arr[i * column + j]相当于注释)来实时查找行的开头(arr + i * column)[j].在第二种方法中,您使用相同的arr_data + i * column公式预先计算所有行开头,并将它们存储在单独的"行索引"数组中以供进一步使用arr.

因此,它基本上归结为内存使用(第一种方法需要更少的内存)和速度(第二种方法可能,但不一定,更快)之间的权衡.同时,第二种方法支持2D数组访问的"自然"语法 - arr[i][j]而在第一种方法中,您必须使用更复杂的1D访问语法和索引重新计算.