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)
指针的指针是从指针到数组分开解释的.我已经能够从各种来源获得部分信息,但没有一个能够内聚地缝合线条.
代码使用单个连续的内存块来容纳二维数组.
char *data = (char *)malloc(rows*cols*sizeof(char));
Run Code Online (Sandbox Code Playgroud)
好的 - 这条线为整个二维阵列分配空间.二维数组是rows
逐cols
列的.所以元素的总数是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]
(用于n
从0
至5
)是第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]
.