动态内存分配代码说明

时间:2011-06-16 23:52:50

标签: 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;
 }

Pointers指针的解释与Pointers to Arrays不同。我已经能够从各种来源获得部分信息,但没有一个能够内聚地缝合线条。

5 个答案:

答案 0 :(得分:5)

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

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

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

malloc调用返回指向已分配内存的指针。由于此内存将用于保存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]是* 地址

那么在这种情况下循环的作用是:

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]。< / p>

答案 1 :(得分:1)

第一个malloc正在获取2D字符数组的内存。第二个malloc为行索引获取内存。

for循环将指针设置为每一行。

最后返回行索引。

答案 2 :(得分:1)

您可以将其创建的二维数组视为一维数组的数组。每个行条目都指向一个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;
}

答案 3 :(得分:1)

难以破译......

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]

的指针

答案 4 :(得分:1)

声明中的每个*都指向一个指针间接层。所以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大的内存。调用(char *)之前的malloc只是将新内存转换为与指针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数组的一行。