我正在尝试返回一个char指针数组,但编译器似乎不喜欢它。
char*[] get_multiple(int x) {
char *tmp[x];
int i;
for (i=0;i<x;i++)
tmp[i]=strdup("abc");
return tmp;
}
编译器出现以下错误:
error: expected identifier or '(' before '[' token
第1行
知道为什么编译器不喜欢它以及如何修复它? (我知道我也可以从调用者传入一个结构来存储返回指针,但我想避免这样做)
答案 0 :(得分:2)
请允许我加入@Lidong Guo的回答(引用如下)
您不能通过以下方式创建数组:
char * tmp[x]
,因为x已知运行时!使用
char **tmp = malloc(x*sizeof(char *));
代替
通过查看您的代码,我可以看到您误解了数组标签tmp
实际代表的内容或tmp
实际位于何处。
在函数中分配变量(或静态大小的数组)时,它存储在当前堆栈框架<堆栈中< / strong>即可。函数返回后,堆栈帧将被销毁/释放,并且不应再次使用/引用该内存!!!
tmp
是一个标签,表示tmp
数组所在的内存地址。这是在堆栈上,所以当你的函数返回时它不再是一个有效的指针!
请原谅我,如果你已经知道这一点,但根据你的术语判断,我怀疑你可能没有。
在C中你不能将数组分配给其他数组!
int array1[10], array2[10];
// ... Put some values into array 1 ...
array2 = array1; // ILLEGAL! DOES NOT COPY AN ARRAY
同样,如果你返回tmp
,你将返回地址,而不是数组,所以如果你将它分配给另一个变量,你应该复制它而不是分配它!
因此C不允许你返回一个数组而你应该返回指针。
但即使你将一个指针返回给tmp
,你也会遇到麻烦,因为你试图分配它(在堆栈上)所以@Lidong Guo建议你即使在函数返回后,也可以将它分配到它可以存活的堆上。但是,这意味着您需要记住释放内存!
所以使用@Lidong Guo的代码重写你的函数看起来像
char** get_multiple(int x) {
char **tmp = malloc(x * sizeof(char*));
int i;
for (i=0;i<x;i++)
tmp[i]=strdup("abc");
return tmp;
}
假设的主人会像这样使用它:
int main()
{
char** multiple7;
multiple7 = get_multiple(7);
// Do some stuff on multiple 7
free(multiple7[3]);
// Do some more stuff ...
// Don't forget to free multiple7 array memory too
free(multiple7);
return 0;
}
答案 1 :(得分:1)
您可以使用两种类型作为函数的返回类型:
您需要做的是声明一个函数,该函数返回指向char或char **
指针的指针。您必须分配足够的内存来存储指向字符串的指针 - 因此,如果您需要7个字符串,则必须分配足够的空间来容纳至少7个char *
个对象 - 然后您必须为7个字符串中的每个字符串分配空间并将这些分配给刚刚分配的char *
。或者,如果此数组中的所有字符串都具有最大长度,则可以声明一个连续的内存块并计算每个字符串的偏移量。
为了帮助进行内存管理,还可以创建一个free_multiple
函数。
char **get_multiple(size_t max)
{
char **multiple = malloc(max * sizeof(*multiple));
for (size_t i = 0; i < max; i++)
multiple[i] = malloc(/* determine max length of string including null terminator */);
return multiple;
}
void free_multiple(char **multiple, size_t max)
{
for (size_t i = 0; i < max; i++)
free(multiple[i]); /* free individual strings */
free(multiple); /* free the container as well */
}
答案 2 :(得分:0)
您不能通过以下方式创建数组:char * tmp[x]
,因为x已知运行时!
使用char **tmp = malloc(x*sizeof(char *));
代替