简体   繁体   English

动态内存分配代码说明

[英]Dynamic memory allocation code explanation

Being a beginner C/C++ programmer, I am having to spend several hours, trying to decipher the code below: Could someone walk me (step me through the code below for dynamic memory allocation) line by line. 作为一名初学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;
 }

Pointer to Pointers is explained separately than from Pointers to Arrays. 指针的指针是从指针到数组分开解释的。 I have been able to get parts of the information from various sources, but none that stitches the lines cohesively. 我已经能够从各种来源获得部分信息,但没有一个能够内聚地缝合线条。

The code is using a single contiguous block of memory to hold a 2-D array. 代码使用单个连续的内存块来容纳二维数组。

char *data = (char *)malloc(rows*cols*sizeof(char));

Ok -- this line is allocating space for the entire 2-D array. 好的 - 这条线为整个二维阵列分配空间。 The 2-D array is rows rows by cols columns. 二维数组是按rows cols列的行。 So the total number of elements is rows * cols . 所以元素的总数是rows * cols Then you have to multiply that by the amount of space each element takes up, which is sizeof(char) since this is a 2-D array of char . 然后你必须乘以每个元素占用的空间量,即sizeof(char)因为这是一个2-D char数组。 Thus the total amount of memory to be allocated is rows * cols * sizeof(char) which is indeed the argument to malloc . 因此,要分配的内存总量是rows * cols * sizeof(char) ,这确实是malloc的参数。

The malloc call returns a pointer to the allocated memory. malloc调用返回指向已分配内存的指针。 Since this memory will be used to hold char , you cast the return value to char * . 由于此内存将用于保存char ,因此将返回值char *char *

char **array= (char **)malloc(rows*sizeof(char*));

array is being declared as type "pointer to pointer to char" because that's what it's going to do. array被声明为类型“指向char的指针”,因为这就是它要做的事情。 It'll point to memory that will hold pointers to char. 它将指向将保存指向char的指针的内存。 It will be one pointer for each row. 它将是每行的一个指针。 So you have to allocate rows * sizeof(char *) memory: the number of pointers times the size of a pointer of the right type. 所以你必须分配rows * sizeof(char *)内存:指针的数量乘以正确类型的指针的大小。 And since this was allocated to point to pointers to char, we cast the return value to char ** . 由于这是分配给指向char的指针,我们将返回值转换为char **

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

This is the magic :). 这是神奇的:)。 This sets each pointer in array to point to within the block of actual data allocated earlier. 此设置每个指针array到早先分配的实际数据块的指向。 Consider a concrete example where rows is 2 and cols is 3. Then you have the block of 6 characters in memory: 考虑一个具体的例子,其中rows是2, cols是3.然后你在内存中有6个字符的块:

 [0][1][2][3][4][5]

And data[n] (for n from 0 to 5 ) is the n-th element and &data[n] is the * address of the n-th element. 并且data[n] (对于n05 )是第n个元素, &data[n]是第n个元素的* 地址

So what that loop does in this case is do: 那么这个循环在这种情况下做的是:

array[0] = &data[0];
array[1] = &data[3];

So array[0] points to the sub-block starting at [0] and array[1] points to the sub-block starting at [3] . 因此, array[0]指向从[0]开始的子块, array[1]指向从[3]开始的子块。 Then when you add the second subscript you're indexing from the start of that pointer. 然后,当您添加第二个下标时,您将从该指针的开头编制索引。 So array[0][2] means "get the pointer stored in array[0] . Find what it points to, then move ahead 2 elements from there.: 所以array[0][2]意思是“将指针存储在array[0] 。找到它指向的内容,然后向前移动2个元素:

array[0] points to [0][1][2] (well, actually points to [0] ). array[0]指向[0][1][2] (实际上指向[0] )。 Then you move two elements ahead and get [2] . 然后你向前移动两个元素并得到[2]

Or if you start with array[1][1] , array[1] points to [3][4][5] (and actually points at [3] . Move one element ahead and get [4] . 或者如果你从array[1][1]array[1]指向[3][4][5] (实际指向[3] 。向前移动一个元素并得到[4]

The first malloc is getting memory for the 2D character array. 第一个malloc是获取2D字符数组的内存。 The second malloc is getting memory for rows index. 第二个malloc正在为行索引获取内存。

The for loop is setting the pointer to each row. for循环将指针设置为每一行。

Finally the row index is returned. 最后返回行索引。

You can think of the 2-D array that it is creating as an array of single-dimensional arrays. 您可以将其创建的二维数组视为一维数组的数组。 Each row entry points to an array of char that represents the column data for that row. 每个行条目都指向一个char数组,表示该行的列数据。

The following is the original code with comments added to attempt to describe each step: 以下是添加了注释的原始代码,以尝试描述每个步骤:

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;
}

Is not hard to decipher... 难以破译......

char *data = (char *)malloc(rows*cols*sizeof(char));

simple memory allocation 简单的内存分配

char **array= (char **)malloc(rows*sizeof(char*));

memory allocation of #row char pointers #row char指针的内存分配

array[i] = &(data[cols*i]);

every array[i] is a pointer, a pointer to data[cols*i] 每个数组[i]都是一个指针,一个指向数据的指针[cols * i]

Each * in a declaration refers to one level of pointer indirection. 声明中的每个*指的是指针间接的一个级别。 so int ** means a pointer to a pointer to an int. 所以int **表示指向int **的指针。 So your function: 所以你的功能:

char **alloc_2d_char(const int rows, const int cols) 
{

returns a pointer to a pointer to a char. 返回指向char的指针。

  char *data = (char *)malloc(rows*cols*sizeof(char));

This declares a pointer to a char . 这声明了一个指向char的指针。 The pointer is called data . 指针称为data The initialization calls malloc , which allocates a number of bytes equal to the value of the argument. 初始化调用malloc ,它分配一些等于参数值的字节。 This means there are rows*cols*sizeof(char) bytes, which will be equal to rows*cols , since a char is 1 byte. 这意味着有rows*cols*sizeof(char)字节,它们将等于rows*cols ,因为char是1个字节。 The malloc function returns the pointer to the new memory , which means that data now points to a chunk of memory that's rows*cols big. malloc函数返回指向新内存的指针 ,这意味着data现在指向rows*cols大的内存块。 The (char *) before the call to malloc just casts the new memory to the same type as the pointer data . 调用malloc之前的(char *)只是将新内存转换为与指针data相同的类型。

  char **array= (char **)malloc(rows*sizeof(char*));

array is a pointer to a pointer to a char . array是指向char的指针。 It is also being assigned using malloc . 它也是使用malloc分配的。 The amount of memory being allocated this time is rows*sizeof(char) , which is equal to rows . 这次分配的内存量是rows*sizeof(char) ,它等于rows This means that array is a pointer to a pointer to a chunk of memory big enough to hold 1 row. 这意味着array是一个指向指向大块内存的指针的指针,该内存大到足以容纳1行。

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

The rest of your code initializes each element of array to hold the address of the corresponding row of the big chunk of memory. 其余的代码初始化array每个元素以保存大块内存的相应行的地址。 Your data pointer will point to a chunk of memory that looks like this: 您的data指针将指向一块如下所示的内存:

col:   0 1 2 3 ... cols-1
row: 0 *
     1 *
     2 *
     3 *
     .
     .
     .
rows-1 *

And your array pointer will point to a chunk of memory with a list of pointers, each of which points to one of the asterisks in the memory chunk above. 并且你的array指针将指向一块内存,其中包含一个指针列表,每个指针都指向上面内存块中的一个星号。

   return array;
 }

This just returns your array pointer to a pointer, which matches the return type of the alloc_2d_char function: char ** . 这只会将您的array指针返回给指针,该指针与alloc_2d_char函数的返回类型匹配: char ** This means that the caller of the function will essentially obtain an array of pointers, and each of these pointers points to one of the rows of the 2D array. 这意味着函数的调用者将基本上获得指针数组,并且这些指针中的每一个指向2D数组的一行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM