Pregunta

Esto es de una pequeña biblioteca que encontré en línea:

const char* GetHandStateBrief(const PostFlopState* state)
{
    static std::ostringstream out;

    // ... rest of the function ...

    return out.str().c_str()
}

En mi código estoy haciendo esto:

const char *d = GetHandStateBrief(&post);
std::cout<< d << std::endl;

Ahora, al principio d basura contenida. Luego me di cuenta de que la cadena C que estoy obteniendo de la función se destruye cuando la función regresa porque std::ostringstream se asigna en la pila. Entonces agregué:

return strdup( out.str().c_str());

Y ahora puedo obtener el texto que necesito de la función.

Tengo dos preguntas:

  1. ¿Estoy entendiendo esto correctamente?

  2. Más tarde noté que out (de tipo std::ostringstream) se asignó con almacenamiento estático. ¿No significa eso que se supone que el objeto permanece en la memoria hasta que el programa termine? Y si es así, ¿por qué no se puede acceder a la cadena?

¿Fue útil?

Solución

strdup asigna una copia de la cadena en el montón, que debe liberar manualmente más tarde (con free() Pienso). Si tiene la opción, sería mucho mejor regresar std::string.

El almacenamiento estático de out no ayuda, porque .str() Devuelve un temporal std::string, que se destruye cuando la función sale.

Otros consejos

Tienes razón en que out es una variable estática asignada en el segmento de datos. Pero out.str() es un temporal asignado en la pila. Entonces cuando lo haces return out.str().c_str() Estás devolviendo un puntero a los datos internos de una pila temporal. Tenga en cuenta que incluso si una cadena no es una variable de pila, c_str se "solo concede permanecer sin cambios hasta la próxima llamada a una función miembro no constante del objeto de cadena".

Creo que has alcanzado una solución razonable, suponiendo que no puedas simplemente devolver una cadena.

strdup () Devuelve un puntero Char* que apunta a la memoria en el montón. Debe liberarlo () cuando haya terminado, pero sí, eso funcionará.

La variable local estática std::ostringstream out No tiene sentido en este caso, a menos que la cadena std :: que se devuelva también fuera estática, lo que su observación demuestra que no es verdad.

En GetHandStateBrief, variable out no necesita ser estático. Necesitas un explícito static string para reemplazar el temporal que se estaba creando en su llamada original a out.str():

static std::string outStr;
std::ostringstream out;
... rest of function ...
outStr = out.str();
return outStr.c_str();
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top