C语言 将内存分配给双指针?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2257735/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 04:28:51  来源:igfitidea点击:

Assigning memory to double pointer?

cstringpointersmallocdouble-pointer

提问by lazy_hack

I am having trouble understanding how to assign memory to a double pointer. I want to read an array of strings and store it.

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

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

instead of this I just assign a large block of memory and store the string

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

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

would that be wrong? And if so why is it?

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

回答by user7116

Your second example is wrong because each memory location conceptually would not hold a char*but rather a char. If you slightly change your thinking, it can help with this:

您的第二个示例是错误的,因为从概念上讲,每个内存位置都不会包含 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'

Because of that, your first loop would be how you do in C an array of character arrays/pointers. Using a fixed block of memory for an array of character arrays is ok, but you would use a single char*rather than a char**, since you would not have any pointers in the memory, just chars.

因此,您的第一个循环将是您在 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];
}

回答by AnkitSahu

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

may be your typo mistake but your loop should be of 50 instead of 20 if you are looking for 50 x 50 matrix. Also after allocation of memory mentioned above you can access the buffer as ptr[i][j] i.e in the 2D format.

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

回答by Abhishek D K

i will give one example, which might clear of the doubt,

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

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

回答by ravi chandra

other simpler way to memorize

其他更简单的记忆方法

Case -1 :

情况1 :

step-1 : char *p;

第 1 步:字符 *p;

step -2 : please read it like below

步骤-2:请阅读如下

char (*p); ==> p is a pointer to a char

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

now you just need to do malloc for the type (step-2) without braces

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

i.e., p = malloc(sizeof(char) * some_len);

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

Case -2 :

案例-2:

step-1 : char **p;

第 1 步:字符 **p;

step -2 :

第2步 :

please read it like below

请阅读如下

char* (* p); ==> p is a pointer to a char *

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

now you just need to do malloc for the type (step-2) without braces

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

i.e., p = malloc(sizeof(char *) * some_len);

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

Case -3 :

案例-3:

No one uses this but just for sake of explanation

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

char ***p;

字符***p;

read it as,

读作,

char** (*p); ==> p is a pointer to a char** (and for this check case-2 above)

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

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

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

回答by Pent Ploompuu

A double pointer is just a pointer to another pointer. So you can allocate it like this:

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

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

You have to keep in mind where your pointer is stored at (in this example the double pointer points to a pointer variable on the stack so it's invalid after the function returns).

你必须记住你的指针存储在哪里(在这个例子中,双指针指向堆栈上的一个指针变量,所以在函数返回后它是无效的)。

回答by Rohan Saxena

Adding to Pent's answer, as he correctly pointed out, you will not be able to use this double pointer once the function returns, because it will point to a memory location on the function's activation record on stack which is now obsolete (once the function has returned). If you want to use this double pointer after the function has returned, you may do this:

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

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

The return type of the function must obviously be char **for this.

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

回答by MindFold

Double pointer is, simply put, a pointer to a pointer, In many cases it is used as an array of other types.

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

For example, if you want to create an array of strings you can simply do:

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

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

this will create an array of size 10, each element will be a string of length 40.

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

thus you can access this by stringArray[5] and get a string in the 6th position.

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

this is one usage, the others are as mentioned above, a pointer to a pointer, and can be allocated simply by:

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

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

read more here: good array tutorial

在这里阅读更多: 好的阵列教程