函数返回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 ,返回指向不再分配的内存的指针。

从函数“返回”指针/缓冲区有两个选项:

  1. 在调用函数中分配缓冲区并将其传递给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

  2. 在函数内动态分配缓冲区:

     char * out = malloc(256 * sizeof *out); // ... return out; 

    这有利于gen的声明不会改变。 但它确实意味着调用函数在完成它时必须free返回的缓冲区。