将内存分配给双指针?

我无法理解如何为双指针分配内存。 我想读取一个字符串数组并存储它。

char **ptr; fp = fopen("file.txt","r"); ptr = (char**)malloc(sizeof(char*)*50); for(int i=0; i<20; i++) { ptr[i] = (char*)malloc(sizeof(char)*50); fgets(ptr[i],50,fp); } 

而不是这个我只是分配一个大的内存块并存储字符串

  char **ptr; ptr = (char**)malloc(sizeof(char)*50*50); 

那会错吗? 如果是这样,为什么呢?

你的第二个例子是错误的,因为每个内存位置在概念上都不会包含char*而是char 。 如果你稍微改变一下你的想法,它可以帮助解决这个问题:

 char *x; // Memory locations pointed to by x contain 'char' char **y; // Memory locations pointed to by y contain 'char*' x = (char*)malloc(sizeof(char) * 100); // 100 'char' y = (char**)malloc(sizeof(char*) * 100); // 100 'char*' // below is incorrect: y = (char**)malloc(sizeof(char) * 50 * 50); // 2500 'char' not 50 'char*' pointing to 50 'char' 

因此,你的第一个循环将是你在C中如何做一个字符数组/指针数组。 对一个字符数组数组使用固定的内存块是可以的,但你可以使用一个char*而不是char** ,因为你在内存中没有任何指针,只有char

 char *x = calloc(50 * 50, sizeof(char)); for (ii = 0; ii < 50; ++ii) { // Note that each string is just an OFFSET into the memory block // You must be sensitive to this when using these 'strings' char *str = &x[ii * 50]; } 

我将举一个可能没有疑问的例子,

 char **str; // here its kind a equivalent to char *argv[] str = (char **)malloc(sizeof(char *)*2) // here 2 indicates 2 (char*) str[0]=(char *)malloc(sizeof(char)*10) // here 10 indicates 10 (char) str[1]=(char *)malloc(sizeof(char)*10) //  strcpy(str[0],"abcdefghij"); // 10 length character strcpy(str[1],"xyzlmnopqr"); // 10 length character cout< 

双指针只是指向另一个指针的指针。 所以你可以像这样分配它:

 char *realptr=(char*)malloc(1234); char **ptr=&realptr; 

您必须记住指针存储在哪里(在此示例中,双指针指向堆栈上的指针变量,因此在函数返回后它无效)。

其他更简单的记忆方式

情况1 :

step-1:char * p;

第2步:请阅读如下

char(* p); ==> p是指向char的指针

现在你只需要为没有大括号的类型(步骤2)做malloc

即,p = malloc(sizeof(char)* some_len);

案例-2:

第一步:char ** p;

第2步 :

请阅读如下

char *(* p); ==> p是指向char *的指针

现在你只需要为没有大括号的类型(步骤2)做malloc

即,p = malloc(sizeof(char *)* some_len);

案例-3:

没有人使用这个,只是为了解释

char *** p;

读它,

char **(* p); ==> p是指向char **的指针(对于上面的检查案例-2)

p = malloc(sizeof(char **)* some_len);

添加到Pent的答案,正如他正确指出的那样,一旦函数返回,你将无法使用这个双指针,因为它将指向函数在堆栈上的激活记录上的内存位置,现在已经过时(一旦函数具有回)。 如果要在函数返回后使用此双指针,可以执行以下操作:

 char * realptr = (char *) malloc(1234); char ** ptr = (char **) malloc(sizeof(char *)); *ptr = realptr; return ptr; 

为此,函数的返回类型显然必须是char **

  char **ptr; fp = fopen("file.txt","r"); ptr = (char**)malloc(sizeof(char*)*50); for(int i=0; i<50; i++) { ptr[i] = (char*)malloc(sizeof(char)*50); fgets(ptr[i],50,fp); } fclose(fp); 

可能是你的拼写错误,但如果你正在寻找50 x 50矩阵,你的循环应该是50而不是20。 在分配上述内存后,您也可以以ptr [i] [j]的forms访问缓冲区,即2D格式。

简单地说,双指针指向指针,在许多情况下,它被用作其他类型的数组。

例如,如果要创建字符串数组,则可以执行以下操作:

 char** stringArray = calloc(10, 40); 

这将创建一个大小为10的数组,每个元素将是一个长度为40的字符串。

因此你可以通过stringArray [5]访问它并获得第6个位置的字符串。

这是一种用法,其他用法如上所述,指向指针的指针,可以简单地通过以下方式分配:

 char* str = (char*)malloc(40); char** pointerToPointer = &str //Get the address of the str pointer, valid only in the current closure. 

在这里阅读更多: 良好的arrays教程