c++ pointers c-strings

c++ - Uso de la cadena C: "Dirección de la pila de memoria asociada con la variable local devuelta"



pointers c-strings (4)

Usa montón en lugar de pila

Es mejor asignar memoria en el montón para este caso usando:

int* someDataForParams(void *_params) { ... int* charCounts = calloc(96, sizeof(char*)); ... return charCounts; }

96 es solo una longitud de cuerda (solo un número mágico)

No soy programador de C, por lo que no estoy familiarizado con C-string, pero soy nuevo. Tengo que usar una biblioteca de C, así que aquí hay una versión abreviada de mi código para demostrar mi problema:

char** ReadLineImpl::my_completion () { char* matches[1]; matches[0] = "add"; return matches; }

Estoy recibiendo una advertencia:

Advertencia: se devolvió la dirección de la memoria de pila asociada con la variable local ''coincidencias''

Y mi aplicación no parece funcionar correctamente (puede ser debido a esta advertencia).

¿Qué es la advertencia y causará algún problema?


Cuando devuelve la matriz de matches , lo que está devolviendo es la dirección del primer elemento. Esto se almacena en la pila dentro de my_completion . Una vez que regrese de my_completion la memoria se recuperará y (lo más probable) será reutilizada para otra cosa, sobrescribiendo los valores almacenados en las matches , y sí, puede que esa sea la razón por la que su aplicación no funciona, si no es así. ahora, probablemente lo será una vez que haya solucionado algunos otros problemas, o lo haya cambiado un poco, o alguna otra cosa, porque esta no es una de esas pequeñas advertencias que puede ignorar de forma segura.

Puedes arreglar esto de diferentes maneras. Lo más obvio es simplemente usar std::vector<char *> [o mejor aún std::vector<std::string> ] en su lugar:

std::vector<std::string> ReadLineImpl::my_completion () { std::vector<std::string> strings; strings.push_back("add"); return strings; }

Edición: Por lo tanto, si la biblioteca requiere un char ** según la interfaz de línea de readline , use esto:

char** ReadLineImpl::my_completion () { char **matches = static_cast<char **>malloc(1 * sizeof(char *)); matches[1] = "add"; return matches; }

¡Problema resuelto!


cambio

char* matches[1];

a

char *matches = new matches[1];


char* matches[1]; variables char* matches[1]; se declara en la pila y se liberará automáticamente cuando el bloque actual salga del alcance.

Esto significa que cuando devuelva matches , se liberará la memoria reservada para matches y su puntero apuntará a algo que no desea.

Puedes resolver esto de muchas maneras, y algunas de ellas son:

  1. Declare matches[1] como static : static char* matches[1]; - esto asignará espacio para las matches en el montón (esto puede morderle si lo usa de forma inadecuada, ya que todas las instancias de la función my_completion compartirán la misma variable de matches ).

  2. Asigne espacio en la función de llamada y páselo a my_completion function: my_completion(matches) :

    char* matches[1]; matches = my_completion(matches); // ... char** ReadLineImpl::my_completion (char** matches) { matches[0] = "add"; return matches; }

  3. Asigne espacio en la función llamada en el montón (usando malloc , calloc y amigos) y pase la propiedad a la función del que llama, que tendrá que desasignar este espacio cuando ya no sea necesario (utilizando free ).