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

时间:2015-04-23 04:55:34

标签: c arrays malloc

我试图了解动态分配的数组在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;
}

我以为我会得到一个运行时错误,因为我没有分配(成员+ 1),但实际上它确实打印了" john"并且"不应该工作",而且,它出现了* members = malloc(5)行并不是必需的。为什么呢?

4 个答案:

答案 0 :(得分:5)

你的作业没有做你认为他们正在做的事情。分配*members*(members+1)时,您将char*分配给每个字符串文字,而不是将其复制到已分配(或未分配)的堆内存。

相反,如果您用strcpy替换了作业,即:

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

然后,您将在第二次分配时获得访问冲突,但不会在第一次分配时获得访问冲突同样,malloc(5)似乎不必要的原因是因为您将指针重新指定为指向字符串文字,而不是将“john”字符串复制到分配的内存中。

答案 1 :(得分:2)

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

即。会员可以容纳四个成员,每个成员都可以拥有一个字符串的地址。

答案 2 :(得分:1)

一些事情:

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

答案 3 :(得分:1)

Because you have initialized pointer of type char** with 4*sizeof(*members) I think you are planning to store 4 strings, so recommendation is to allocate memory for all 4 strings, like:

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

or you can initialize all pointers with NULL and change them as needed (allocate or point to some allocated memory), e.g.:

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

And in that case you can check with if(members[i] != NULL) to identify items that point data.