动态内存分配代码说明

Ash*_*han 4 c arrays pointers memory-management

作为一名初学C/C++程序员,我不得不花费几个小时,试图破译下面的代码:有人可以一行一步地走我(通过以下代码进行动态内存分配).

 char **alloc_2d_char(const int rows, const int cols) 
 {
   char *data = (char *)malloc(rows*cols*sizeof(char));
   char **array= (char **)malloc(rows*sizeof(char*));

   for (int i=0; i<rows; i++)
      array[i] = &(data[cols*i]);

   return array;
 }
Run Code Online (Sandbox Code Playgroud)

指针的指针是从指针到数组分开解释的.我已经能够从各种来源获得部分信息,但没有一个能够内聚地缝合线条.

Qua*_*nic 5

代码使用单个连续的内存块来容纳二维数组.

char *data = (char *)malloc(rows*cols*sizeof(char));
Run Code Online (Sandbox Code Playgroud)

好的 - 这条线为整个二维阵列分配空间.二维数组是rowscols列的.所以元素的总数是rows * cols.然后你必须乘以每个元素占用的空间量,这是sizeof(char)因为这是一个二维数组char.因此,要分配的内存总量rows * cols * sizeof(char)确实是其中的参数malloc.

malloc调用返回指向已分配内存的指针.由于此内存将用于保存char,因此您将返回值转换为char *.

char **array= (char **)malloc(rows*sizeof(char*));
Run Code Online (Sandbox Code Playgroud)

array被声明为类型"指向char的指针",因为这就是它要做的事情.它将指向将保存指向char的指针的内存.它将是每行的一个指针.所以你必须分配rows * sizeof(char *)内存:指针的数量乘以正确类型的指针的大小.由于这是分配给指向char的指针,我们将返回值转换为char **.

for (int i=0; i<rows; i++)
   array[i] = &(data[cols*i]);
Run Code Online (Sandbox Code Playgroud)

这是神奇的:).此设置每个指针中array,以点早先分配实际数据的块.考虑一个具体的例子,其中rows是2并且cols是3.然后你在内存中有6个字符的块:

 [0][1][2][3][4][5]
Run Code Online (Sandbox Code Playgroud)

data[n](用于n05)是第n个元件和&data[n]是*地址的第n个元素的.

那么这个循环在这种情况下做的是:

array[0] = &data[0];
array[1] = &data[3];
Run Code Online (Sandbox Code Playgroud)

所以array[0]指向子块开始[0]array[1]指向从哪个子块开始[3].然后,当您添加第二个下标时,您将从该指针的开头编制索引.所以array[0][2]意味着"将指针存储起来array[0].找到它指向的内容,然后从那里向前移动2个元素:

array[0]指向[0][1][2](嗯,实际指向[0]).然后你向前移动两个元素并获得[2].

或者,如果你开始array[1][1],array[1]指向[3][4][5](并实际指向[3].向前移动一个元素并得到[4].