函数返回C中局部变量错误的地址
我有以下代码:
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
没有运气。 我错过了什么吗?
您的char
数组变量out
仅存在于函数体内。
当你从函数返回时, out
缓冲区的内容不再被访问,它只是函数的本地 。
如果要将函数中的某些字符串返回给调用者,可以在函数内动态分配该字符串(例如,使用malloc()
)并将指向该字符串的指针返回给调用者,例如
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 ++,最简单的方法是使用像std::string
这样的字符串类 (让它管理所有的字符串缓冲区内存分配/清理)。
在函数char out[256];
使用以下声明时char out[256];
一旦函数返回,分配的空间将被释放,因此返回指向out
char
数组的指针是没有意义的。
如果要返回指向您在函数中创建的字符串的指针,则应使用malloc()
如下所示
char* out = (char*)malloc(256*sizeof(char));
它为256个char
分配空间,但应该使用free()
函数在某些时候手动释放。
或者正如Brian Bi的评论中所建议的那样,传递一个char *
,它指向你想用作函数参数的字符串。
问题是当函数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]){
这意味着你必须为
gen
(没有其他指针或数组)提供char[256]
类型的变量。 但它确实允许你在内部做sizeof out
。 -
在函数内动态分配缓冲区:
char * out = malloc(256 * sizeof *out); // ... return out;
这有利于
gen
的声明不会改变。 但它确实意味着调用函数在完成它时必须free
返回的缓冲区。