Function returning address of local variable error in C
Your char
array variable out
exists only inside the function's body.
When you return from the function, the content of out
buffer can't be accessed anymore, it's just local to the function.
If you want to return some string from your function to the caller, you can dynamically allocate that string inside the function (e.g. using malloc()
) and return a pointer to that string to the caller, e.g.
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).
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. 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).
When you use the following declaration in the function 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.
If you want to return a pointer to a string you create in the function you should use malloc()
as in
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.
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.
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. So, when you return out
you return a pointer to memory that is no longer allocated.
There are two options to 'return' a pointer/buffer from a function:
-
Allocate the buffer in the calling function and pass it to
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:
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):void gen(char out[256]){
That means you must provide a variable of type
char[256]
togen
(and no other pointers or arrays). But it does allow you to dosizeof out
insidegen
. -
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. But it does mean that the calling function has tofree
the returned buffer when its done with it.