简体   繁体   English

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

[英]Function returning address of local variable error in C

I have the following code:我有以下代码:

 char* gen()
 {
     char out[256];
     sprintf(out, ...); // you don't need to know what's in here I don't think

     return out;
 }

And I am getting this error when I try to compile:当我尝试编译时出现此错误:

ERROR: function returns address of local variable

I've tried having this return char[] and char with no luck.我试过让这个返回char[]char没有运气。 Am I missing something?我错过了什么吗?

Your char array variable out exists only inside the function's body.你的char数组变量out只存在于功能的体内
When you return from the function, the content of out buffer can't be accessed anymore, it's just local to the function.当您从函数返回时,不能再访问out缓冲区的内容,它只是函数的本地内容

If you want to return some string from your function to the caller, you can dynamically allocate that string inside the function (eg using malloc() ) and return a pointer to that string to the caller, eg如果您想从函数返回一些字符串给调用者,您可以在函数内部动态分配该字符串(例如使用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(). */
}

Another simpler option would be to pass the out buffer pointer as a char* parameter, along with a buffer size (to avoid buffer overruns).另一个更简单的选择是将out缓冲区指针作为char*参数以及缓冲区大小(以避免缓冲区溢出)传递。

In this case, your function can directly format the string into the destination buffer passed as parameter:在这种情况下,您的函数可以直接将字符串格式化为作为参数传递的目标缓冲区:

/* 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, ...);
    ...
}

Note that you explicitly stated "C" in your question title, but you added a [c++] tag.请注意,您在问题标题中明确指出了“C”,但您添加了[c++]标签。 If you can use C++, the simplest thing to do is to use a string class like std::string (and let it manage all the string buffer memory allocation/cleanup).如果您可以使用 C++,最简单的做法是使用像std::string这样的字符串(并让它管理所有字符串缓冲区内存分配/清理)。

When you use the following declaration in the function char out[256];当您在函数char out[256];使用以下声明时char out[256]; the space allocated will be freed once the function returns, so it doesn't make sense to return a pointer to the out char array.一旦函数返回,分配的空间将被释放,因此返回指向out char数组的指针是没有意义的。

If you want to return a pointer to a string you create in the function you should use malloc() as in如果你想返回一个指向你在函数中创建的字符串的指针,你应该使用malloc()作为

char* out = (char*)malloc(256*sizeof(char));

which allocates space for 256 char s but should be freed manually at some point with the free() function.它为 256 个char分配空间,但应该在某个时候使用free()函数手动释放。

Or as suggested in the comment by Brian Bi pass a char * that points to the string you want to use as an argument to your function.或者按照Brian Bi的评论中的建议,传递一个char *指向要用作函数参数的字符串。

The problem is that when the function gen returns (exits) its local variables (such as out ) run out of scope and are no longer accessible to the caller.问题是当函数gen返回(退出)时,它的局部变量(例如out )超出了作用域并且调用者不再可以访问它。 So, when you return out you return a pointer to memory that is no longer allocated.因此,当您返回out您会返回一个指向不再分配的内存的指针。

There are two options to 'return' a pointer/buffer from a function:从函数“返回”指针/缓冲区有两种选择:

  1. Allocate the buffer in the calling function and pass it to gen :在调用函数中分配缓冲区并将其传递给gen

     char out[256]; gen(out, sizeof out);

    it is common to also provide the size of the buffer you pass in, since the called function cannot know this.通常还提供您传入的缓冲区的大小,因为被调用的函数无法知道这一点。 This means that you have to change the declaration of gen to:这意味着您必须将 gen 的声明更改为:

     void gen(char * out, size_t size){

    You could also hard-code the size of the incoming buffer to 256 (since you have it hard-coded in your gen function right now):您还可以将传入缓冲区的大小硬编码为 256(因为您现在已在gen函数中对其进行了硬编码):

     void gen(char out[256]){

    That means you must provide a variable of type char[256] to gen (and no other pointers or arrays).这意味着您必须gen提供一个char[256]类型的变量(并且没有其他指针或数组)。 But it does allow you to do sizeof out inside gen .但它确实允许您gen内部执行sizeof out

  2. Allocate the buffer dynamically inside the function:在函数内部动态分配缓冲区:

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

    this has as advantage that the declaration of gen does not change.这样做的好处是gen的声明不会改变。 But it does mean that the calling function has to free the returned buffer when its done with it.但这确实意味着调用函数在完成后必须free返回的缓冲区。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM