Función que devuelve la dirección del error de variable local en C

Tengo el siguiente código:

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

Y obtengo este error cuando bash comstackr:

 ERROR: function returns address of local variable 

Intenté tener este retorno char[] y char sin suerte. ¿Me estoy perdiendo de algo?

Su variable de array char existe solo dentro del cuerpo de la función.
Cuando regresas de la función, ya no se puede acceder al contenido del búfer de out , solo es local para la función.

Si desea devolver una cadena de su función a la persona que llama, puede asignar dinámicamente esa cadena dentro de la función (por ejemplo, utilizando malloc() ) y devolver un puntero a esa cadena a la persona que llama, por ejemplo,

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

Otra opción más simple sería pasar el puntero del búfer de out como un parámetro char* , junto con un tamaño de búfer (para evitar sobrepasamientos del búfer).

En este caso, su función puede formatear directamente la cadena en el búfer de destino pasado como parámetro:

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

Tenga en cuenta que declaró explícitamente “C” en el título de su pregunta, pero agregó una etiqueta [c++] . Si puede usar C ++, lo más simple es usar una clase de cadena como std::string (y dejar que administre toda la asignación / limpieza de memoria del búfer de cadena).

Cuando utiliza la siguiente statement en la función char out[256]; el espacio asignado se liberará una vez que la función regrese, por lo que no tiene sentido devolver un puntero a la matriz de char out .

Si desea devolver un puntero a una cadena que cree en la función, debe usar malloc() como en

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

que asigna espacio para 256 caracteres pero debe liberarse manualmente en algún momento con la función free() .

O como se sugiere en el comentario de Brian Bi, pase un char * que apunte a la cadena que desea usar como argumento para su función.

El problema es que cuando la función gen regresa (sale), sus variables locales (como out ) se quedan fuera del scope y ya no son accesibles para la persona que llama. Entonces, cuando regresas out devuelves un puntero a la memoria que ya no está asignada.

Hay dos opciones para ‘devolver’ un puntero / buffer desde una función:

  1. Asigne el búfer en la función de llamada y páselo a gen :

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

    es común también proporcionar el tamaño del búfer que pasa, ya que la función llamada no puede saber esto. Esto significa que debe cambiar la statement de gen a:

     void gen(char * out, size_t size){ 

    También podría codificar el tamaño del búfer entrante en 256 (dado que ahora lo tiene codificado en su función gen ):

     void gen(char out[256]){ 

    Eso significa que debe proporcionar una variable de tipo char[256] a gen (y ningún otro puntero o matriz). Pero te permite hacer sizeof out dentro gen .

  2. Asigne el buffer de forma dinámica dentro de la función:

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

    esto tiene como ventaja que la statement de gen no cambia. Pero sí significa que la función de llamada debe free el búfer devuelto cuando haya terminado.