函数返回C中局部变量错误的地址

时间:2014-03-09 22:11:40

标签: 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没有运气。我错过了什么吗?

3 个答案:

答案 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时,您将返回一个指向不再分配的内存的指针。

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

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

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

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

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