我试图了解动态分配的数组在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)行并不是必需的。为什么呢?
答案 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)
一些事情:
malloc(4*sizeof(*members))
,您可以更清楚地使用您尝试为其分配空间的对象的类型,例如malloc(4 * sizeof(char *))
而不是使用变量的名称。 编辑,正如cmaster所指出的,如果你改变变量的类型而不改变malloc()
中的类型,这可能会导致问题,所以请理解这个建议。*members=malloc(5);
是不必要的,因为您的编译器已为您分配了字符串"john"
的空间,并且*members="john";
的工作原理是将字符串数组的索引0处的指针设置为分配的编译器的地址 {/ 1}} "john"
实际 工作。*(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.