[英]Dynamic memory allocation code explanation
作為一名初學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;
}
指針的指針是從指針到數組分開解釋的。 我已經能夠從各種來源獲得部分信息,但沒有一個能夠內聚地縫合線條。
代碼使用單個連續的內存塊來容納二維數組。
char *data = (char *)malloc(rows*cols*sizeof(char));
好的 - 這條線為整個二維陣列分配空間。 二維數組是按rows
cols
列的行。 所以元素的總數是rows * cols
。 然后你必須乘以每個元素占用的空間量,即sizeof(char)
因為這是一個2-D char
數組。 因此,要分配的內存總量是rows * cols * sizeof(char)
,這確實是malloc
的參數。
malloc
調用返回指向已分配內存的指針。 由於此內存將用於保存char
,因此將返回值char *
為char *
。
char **array= (char **)malloc(rows*sizeof(char*));
array
被聲明為類型“指向char的指針”,因為這就是它要做的事情。 它將指向將保存指向char的指針的內存。 它將是每行的一個指針。 所以你必須分配rows * sizeof(char *)
內存:指針的數量乘以正確類型的指針的大小。 由於這是分配給指向char的指針,我們將返回值轉換為char **
。
for (int i=0; i<rows; i++)
array[i] = &(data[cols*i]);
這是神奇的:)。 此設置每個指針array
到早先分配的實際數據塊內的指向。 考慮一個具體的例子,其中rows
是2, cols
是3.然后你在內存中有6個字符的塊:
[0][1][2][3][4][5]
並且data[n]
(對於n
從0
到5
)是第n個元素, &data[n]
是第n個元素的* 地址 。
那么這個循環在這種情況下做的是:
array[0] = &data[0];
array[1] = &data[3];
因此, 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]
。
第一個malloc是獲取2D字符數組的內存。 第二個malloc正在為行索引獲取內存。
for循環將指針設置為每一行。
最后返回行索引。
您可以將其創建的二維數組視為一維數組的數組。 每個行條目都指向一個char數組,表示該行的列數據。
以下是添加了注釋的原始代碼,以嘗試描述每個步驟:
char **alloc_2d_char(const int rows, const int cols)
{
// This allocates the chunk of memory that stores that actual data.
// It is a one single-dimensional array that has rows*cols characters.
char *data = (char *)malloc(rows*cols*sizeof(char));
// This allocates an array of pointers that will then be assigned to the
// individual rows (carved out of the previous allocation).
char **array= (char **)malloc(rows*sizeof(char*));
// This assigns each row to the appropriate position in the data array.
// The &(data[cols*i]) bit of it is the address of a portion in the
// memory pointed to by data. The cols*i is the offset to the portion that
// represents row i.
for (int i=0; i<rows; i++)
array[i] = &(data[cols*i]);
// After doing this, then you can assign a value such as:
// array[r][c] = 'x';
// That statement would store 'x' into data[r*c + c]
return array;
}
難以破譯......
char *data = (char *)malloc(rows*cols*sizeof(char));
簡單的內存分配
char **array= (char **)malloc(rows*sizeof(char*));
#row char指針的內存分配
array[i] = &(data[cols*i]);
每個數組[i]都是一個指針,一個指向數據的指針[cols * i]
聲明中的每個*
指的是指針間接的一個級別。 所以int **
表示指向int **
的指針。 所以你的功能:
char **alloc_2d_char(const int rows, const int cols)
{
返回指向char的指針。
char *data = (char *)malloc(rows*cols*sizeof(char));
這聲明了一個指向char
的指針。 指針稱為data
。 初始化調用malloc
,它分配一些等於參數值的字節。 這意味着有rows*cols*sizeof(char)
字節,它們將等於rows*cols
,因為char
是1個字節。 malloc
函數返回指向新內存的指針 ,這意味着data
現在指向rows*cols
大的內存塊。 調用malloc
之前的(char *)
只是將新內存轉換為與指針data
相同的類型。
char **array= (char **)malloc(rows*sizeof(char*));
array
是指向char
的指針。 它也是使用malloc
分配的。 這次分配的內存量是rows*sizeof(char)
,它等於rows
。 這意味着array
是一個指向指向大塊內存的指針的指針,該內存大到足以容納1行。
for (int i=0; i<rows; i++)
array[i] = &(data[cols*i]);
其余的代碼初始化array
每個元素以保存大塊內存的相應行的地址。 您的data
指針將指向一塊如下所示的內存:
col: 0 1 2 3 ... cols-1
row: 0 *
1 *
2 *
3 *
.
.
.
rows-1 *
並且你的array
指針將指向一塊內存,其中包含一個指針列表,每個指針都指向上面內存塊中的一個星號。
return array;
}
這只會將您的array
指針返回給指針,該指針與alloc_2d_char
函數的返回類型匹配: char **
。 這意味着函數的調用者將基本上獲得指針數組,並且這些指針中的每一個指向2D數組的一行。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.