从函数返回的字符串数组不能按预期工作
我试图将一个字符串数组传递给一个函数,在这个函数内部对它进行一些更改,然后将它传递回main()
并打印它以查看更改。 它没有按预期工作。 请告诉我哪里出错了。
#include #include #include //don't forget to declare this function char** fun(char [][20]); int main(void) { char strar[10][20] = { {"abc"}, {"def"}, {"ghi"}, {""},{""} }; //make sure 10 is added char** ret; //no need to allocate anything for ret, ret is just a placeholder, allocation everything done in fun int i = 0; ret = fun(strar); for(i=0;i<4;i++) printf("[%s] ",ret[i]); printf("\n"); return 0; } //don't forget function has to return char** and not int. (Remember char**, not char*) char** fun(char strar[][20]) { int i = 0; char** ret; ret = malloc(sizeof(void*)); //sizeof(void*) is enough, it just has to hold an address for(i=0;i<5;i++) { ret[i] = malloc(20 * sizeof(char)); strcpy(ret[i],strar[i]); } strcpy(ret[3],"fromfun"); return ret; }
您需要确保为ret数组分配完整的指针数组。
//don't forget function has to return char** and not int. (Remember char**, not char*) char** fun(char strar[][20]) { int i = 0; char** ret; ret = malloc(sizeof(void*) * 5); //sizeof(void*) is enough, it just has to hold an address for(i=0;i<5;i++) { ret[i] = malloc(20 * sizeof(char)); strcpy(ret[i],strar[i]); } strcpy(ret[3],"fromfun"); return ret; }
我可以看到的主要问题是内存溢出。
您分配内存来容纳一个元素
ret = malloc(sizeof(void*));
但是,你要放5个元素。
for(i=0;i<5;i++) { ret[i] = malloc(20 * sizeof(char));....
这是未定义的行为 。 访问超出分配的内存。
ret
的内存分配应该是这样的
ret = malloc(5 * sizeof(char *));
要么
ret = malloc(5 * sizeof*ret); //portable
详细说明所做的更改
- 分配单个元素大小的5倍,因为我们将存储5个元素。
- 严格地说,因为
ret
是char **
类型,我们需要在计算要为ret
分配的大小时使用char *
而不是void *
。 - 使用
sizeof *ret
的变化使得代码更加健壮,因为将来,如果ret
的类型变为其他类型,则不需要在此分配中重复类型更改,因为分配将取决于无论如何,*ret
类型。
注意:FWIW,只有在参数为数据类型(如sizeof(int)
情况下,才需要围绕sizeof
参数的括号。 在使用变量名作为参数的情况下,括号是可选的,即sizeof(*ptr)
和sizeof *ptr
都是完全有效和合法的。
那说,
- 在使用返回的指针之前,请务必检查
malloc()
是否成功 - 在
C
,sizeof(char)
保证为1
。 使用相同的乘数是多余的。