簡體   English   中英

動態內存分配代碼說明

[英]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] (對於n05 )是第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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM