繁体   English   中英

在C中动态分配的字符串数组

[英]Dynamically allocated string arrays in C

我试图了解如何在C 99中动态分配数组。无论如何,我有以下代码:

int main()
{
    char** members=malloc(4*sizeof(*members));
    *members=malloc(5);
    *members="john";
    *(members+1)="shouldn't work";
    printf("%s \n",*members);
    printf("%s",*(members+1));
    return 0;
}

我以为会得到运行时错误,因为我没有分配(members + 1),但实际上它确实打印了“ john”和“ should't work”,而且,它还评估了* members = malloc(5 )行不是必需的。 为什么?

您的作业没有按照您认为的去做。 当您分配*members*(members+1) ,您是在将char*分配给每个字符串文字,而不是将其复制到已分配(或未分配)的堆内存中。

相反,如果您用strcpy替换您的分配,即:

strcpy(*members, "john");
strcpy(*(members+1), "shouldn't work");

然后,您将在第二个任务上遇到访问冲突,但不会遇到第一个任务。 同样,看起来malloc(5)不必要的原因是因为您重新分配了指向字符串文字的指针,而不是将“ john”字符串复制到分配的内存中。

char** members=malloc(4*sizeof(*members));

这意味着您已经创建了一个数组,并为可以存储字符串地址的四个元素分配了内存。

因此,如果删除行* members = malloc(5); 然后它也会起作用。

int main()
{
char** members=malloc(4*sizeof(*members));
//*members=malloc(5);
*members="john";
*(members+1)="shouldn't work";
printf("%s \n",*members);
printf("%s",*(members+1));
return 0;
}

也就是说,成员可以容纳四个成员,每个成员可以容纳字符串的地址。

一些东西:

  1. 对于第一个malloc, malloc(4*sizeof(*members)) ,如果要使用要为其分配空间的对象的类型 ,将更加清楚,例如malloc(4 * sizeof(char *))而不是使用变量名。 编辑:正如cmaster指出的那样,如果您更改变量的类型而不更改malloc()的类型,则可能会导致问题,因此请谨慎考虑此建议
  2. *members=malloc(5); 在您的情况下是没有必要的,因为您的编译器已经为您的字符串"john"分配了空间,并且
  3. *members="john"; 通过将字符串数组索引0处的指针设置为分配给"john"的编译器的地址来工作
  4. 同样, *(members+1)="shouldn't work"; 实际上因为在3中提到的点的工作。
  5. 最后,由于这一行- *members="john"; -您丢失了指向malloc(5)所存储的内存的指针,因此该内存将被泄漏:)

因为您已经使用4*sizeof(*members)初始化了char**类型的指针,所以我认为您打算存储4个字符串,因此建议为所有4个字符串分配内存,例如:

char** members=malloc(4*sizeof(*members));
int i;
for(i = 0; i < 4; i++)
    members[i] = malloc(100 + 1);  // 100 is a max length of string
              // actually length of each string can be different

或者您可以使用NULL初始化所有指针,然后根据需要更改它们(分配或指向某些已分配的内存),例如:

char** members=malloc(4*sizeof(*members));
int i;
for(i = 0; i < 4; i++)
    members[i] = NULL;  
// ... somewhere ....
char str[] = "Some string";
members[2] = str;
// ... somewhere else ....
members[1] = malloc(20);
scanf("%19s", members[1]); 

在这种情况下,您可以检查if(members[i] != NULL)以标识指向数据的项目。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM