我有以下代码:
char* gen()
{
char out[256];
sprintf(out, ...); // you don't need to know what's in here I don't think
return out;
}
我在尝试编译时收到此错误:
ERROR: function returns address of local variable
我尝试过这次返回char[]
和char
没有运气。我错过了什么吗?
答案 0 :(得分:4)
您的char
数组变量out
仅存在 函数体内。
当你从函数返回时,out
缓冲区的内容不再被访问,它只是函数的 local 。
如果要将函数中的某些字符串返回给调用者,可以动态在函数内部分配该字符串(例如使用malloc()
)并返回指针< / em>到调用者的那个字符串,例如
char* gen(void)
{
char out[256];
sprintf(out, ...);
/*
* This does NOT work, since "out" is local to the function.
*
* return out;
*/
/* Dynamically allocate the string */
char* result = malloc(strlen(out) + 1) /* +1 for terminating NUL */
/* Deep-copy the string from temporary buffer to return value buffer */
strcpy(result, out);
/* Return the pointer to the dynamically allocated buffer */
return result;
/* NOTE: The caller must FREE this memory using free(). */
}
另一个更简单的选择是将out
缓冲区指针作为char*
参数传递,以及缓冲区大小(以避免缓冲区溢出)。
在这种情况下,您的函数可以直接将字符串格式化为作为参数传递的目标缓冲区:
/* Pass destination buffer pointer and buffer size */
void gen(char* out, size_t out_size)
{
/* Directly write into caller supplied buffer.
* Note: Use a "safe" function like snprintf(), to avoid buffer overruns.
*/
snprintf(out, out_size, ...);
...
}
请注意,您在问题标题中明确声明了“C”,但添加了[c++]
标记。如果您可以使用C ++,最简单的方法是使用字符串 class ,如std::string
(并让它管理所有字符串缓冲区内存分配/清理)。
答案 1 :(得分:3)
当您在函数char out[256];
中使用以下声明时,一旦函数返回,将释放分配的空间,因此返回指向out
{{1}的指针没有意义} array。
如果你想返回一个指向你在函数中创建的字符串的指针,你应该使用malloc()
,如
char
为256 char* out = (char*)malloc(256*sizeof(char));
分配空间,但应使用free()
函数在某个时间点手动释放。
或者按照Brian Bi的评论中的建议传递char
,指向您要用作函数参数的字符串。
答案 2 :(得分:1)
问题是,当函数gen
返回(退出)时,其局部变量(例如out
)超出范围,调用者无法再访问它。因此,当您返回out
时,您将返回一个指向不再分配的内存的指针。
有两个选项可以从函数中“返回”指针/缓冲区:
在调用函数中分配缓冲区并将其传递给gen
:
char out[256];
gen(out, sizeof out);
通常还会提供传入的缓冲区的大小,因为被调用的函数无法知道这一点。这意味着您必须将gen的声明更改为:
void gen(char * out, size_t size){
您还可以将传入缓冲区的大小硬编码为256(因为您现在在gen
函数中对其进行了硬编码):
void gen(char out[256]){
这意味着必须向char[256]
提供gen
类型的变量(并且没有其他指针或数组)。但它允许您在 sizeof out
内执行gen
。
在函数内动态分配缓冲区:
char * out = malloc(256 * sizeof *out);
// ...
return out;
这有利于gen
的声明不会改变。但它确实意味着调用函数在完成后必须free
返回缓冲区。