我试图将一个字符串数组传递给一个函数,在这个函数中对它进行一些更改,并将其传递回main()并打印它以查看更改.它没有按预期工作.请告诉我我哪里出错了.
#include <stdio.h>
#include <string.h>
#include <malloc.h>
//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;
}
Run Code Online (Sandbox Code Playgroud)
我可以看到的主要问题是内存溢出.
您分配内存来容纳一个元素
ret = malloc(sizeof(void*));
Run Code Online (Sandbox Code Playgroud)
但是,你要放5个元素.
for(i=0;i<5;i++)
{
ret[i] = malloc(20 * sizeof(char));....
Run Code Online (Sandbox Code Playgroud)
这是 未定义的行为.访问超出分配的内存.
内存分配ret应该是这样的
ret = malloc(5 * sizeof(char *));
Run Code Online (Sandbox Code Playgroud)
要么
ret = malloc(5 * sizeof*ret); //portable
Run Code Online (Sandbox Code Playgroud)
详细说明所做的更改
ret类型char **,我们需要char *在计算要分配的大小时使用,而ret不是a void *.sizeof *ret使得代码更加健壮,如将来,如果retget 的类型改变为其他类型,则不需要在此分配中重复类型更改,因为分配将取决于类型*ret,无论如何.注意:FWIW,sizeof只有在参数为数据类型的情况下才需要参数周围的括号sizeof(int).在使用一个变量名作为参数的情况下,括号是可选的,即,两个sizeof(*ptr)和sizeof *ptr都完全有效的,合法.
那说,
malloc()在使用返回的指针之前,请务必检查是否成功C,sizeof(char)保证是1.使用相同的乘数是多余的.您需要确保为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;
}
Run Code Online (Sandbox Code Playgroud)