C 为双指针分配内存?

C 为双指针分配内存?,c,string,pointers,malloc,double-pointer,C,String,Pointers,Malloc,Double Pointer,我很难理解如何分配内存 指向双指针。 我想读取字符串数组并存储它 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;
    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 *realptr=(char*)malloc(1234);
char **ptr=&realptr;

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

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

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

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.
请在此处阅读更多信息:
您的第二个示例是错误的,因为从概念上讲,每个内存位置都不会保存
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
s

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*x=calloc(50*50,sizeof(char));
对于(ii=0;ii<50;++ii){
//请注意,每个字符串只是内存块中的一个偏移量
//使用这些“字符串”时,您必须对此敏感
char*str=&x[ii*50];
}

其他更简单的记忆方法

案例-1:

步骤1:字符*p

第2步: 请像下面这样读

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

现在您只需要对类型执行malloc(步骤2),而不使用大括号

i、 e,p=malloc(sizeof(char)*某些元素)

案例-2:

步骤1:字符**p

第2步:

请像下面这样读

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

现在您只需要对类型执行malloc(步骤2),而不使用大括号

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

案例-3:

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

字符***p

读作

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


p=malloc(sizeof(char**)*部分长度)

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

char * realptr = (char *) malloc(1234);
char ** ptr = (char **) malloc(sizeof(char *));
*ptr = realptr;
return ptr;
函数的返回类型显然必须是
char**

char**ptr;
 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);
fp=fopen(“file.txt”,“r”); ptr=(char**)malloc(sizeof(char*)*50);
对于(int i=0;i我将给出一个例子,这可能是毫无疑问的

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);
char**str;//这里它的种类相当于char*argv[]
str=(char**)malloc(sizeof(char*)*2)//这里2表示2(char*)
str[0]=(char*)malloc(sizeof(char)*10)//这里10表示10(char)
str[1]=(char*)malloc(sizeof(char)*10)//
strcpy(str[0],“abcdefghij”);//10个长度字符
strcpy(str[1],“xyzlmnopqr”);//10个长度字符

不能称之为“双指针”-这会让你在精神上走错方向-它是指向指针的指针。在C语言中,不要将调用的结果强制转换为
malloc()
realloc()
,或
calloc())
-这是不必要的,可能会掩盖丢失原型的严重错误。不,这会创建一个100字符*的数组,假设字符*占用4个字节。Hans说的是正确的。此外,100字符*的数组被初始化为0(因为您使用了calloc)因此,所有这些字符*都指向null,访问该数组位置将导致错误。最后一行不应该是
char*str=x+(ii*50)
?并且不要强制转换
malloc()的结果。
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);