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

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

1。

int **arr; arr = malloc( sizeof(int) * row * column ); 

2。

  int **arr; arr = malloc( sizeof(*arr) * row); for(i=0; i<row; i++) arr[i] = malloc( sizeof( **arr) * column)); 

  • 首先,“影响”是你的第一种方法被打破。 它不能通过int **指针工作。

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

     int *arr = malloc( row * column * sizeof *arr ); // Note: `int *`, not `int **` 

    并通过手动索引重新计算来执行访问,例如,而不是做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 ); 

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

     for (i = 0; i < row; i++) arr[i] = arr_data + i * column; 

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

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

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