19

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

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

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

4

7 回答 7

16

您的第二个示例是错误的,因为从概念上讲,每个内存位置都不会包含 achar*而是 a 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 中执行字符数组/指针数组。对字符数组数组使用固定的内存块是可以的,但是您将使用 singlechar*而不是 a char**,因为内存中没有任何指针,只有chars。

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];
}
于 2010-02-13T14:00:50.187 回答
5
 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] 的形式访问缓冲区,即 2D 格式。

于 2018-05-18T10:21:02.493 回答
2

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

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

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

于 2010-02-13T13:50:52.227 回答
2

我将举一个例子,这可能会消除疑问,

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)   // <same as above>

strcpy(str[0],"abcdefghij");   // 10 length character 
strcpy(str[1],"xyzlmnopqr");   // 10 length character

cout<<str[0]<<endl;    // to print the string in case of c++
cout<<str[1]<<endl;    // to print the string in case of c++

or

printf("%s",str[0]);
printf("%s",str[1]);  

//finally most important thing, dont't forget to free the allocated mem
free(str[0]);
free(str[1]);
free(str);
于 2018-06-23T19:43:38.440 回答
1

其他更简单的记忆方法

情况1 :

第 1 步:字符 *p;

步骤-2:请阅读如下

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

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

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

案例-2:

第 1 步:字符 **p;

第2步 :

请像下面这样阅读

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

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

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

案例-3:

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

字符***p;

读作,

字符** (*p); ==> p 是一个指向 char** 的指针(对于上面的这个检查 case-2)

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

于 2016-04-05T20:10:05.813 回答
0

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

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

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

于 2017-03-03T14:17:03.843 回答
-5

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

例如,如果您想创建一个字符串数组,您可以简单地执行以下操作:

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.

在这里阅读更多: 好的数组教程

于 2010-02-13T14:00:36.613 回答