Restituendo 'c_str' da una funzione
-
27-09-2019 - |
Domanda
Questo proviene da una piccola biblioteca che ho trovato online:
const char* GetHandStateBrief(const PostFlopState* state)
{
static std::ostringstream out;
// ... rest of the function ...
return out.str().c_str()
}
Nel mio codice lo sto facendo:
const char *d = GetHandStateBrief(&post);
std::cout<< d << std::endl;
Ora, all'inizio d
contenuto immondizia. Mi sono poi reso conto che la stringa C che sto ottenendo dalla funzione viene distrutta quando la funzione ritorna perché std::ostringstream
è assegnato sullo stack. Quindi ho aggiunto:
return strdup( out.str().c_str());
E ora posso ottenere il testo di cui ho bisogno dalla funzione.
Ho due domande:
Lo capisco correttamente?
In seguito l'ho notato
out
(di tipostd::ostringstream
) è stato assegnato con archiviazione statica. Ciò non significa che l'oggetto dovrebbe rimanere in memoria fino a quando il programma non termina? E se è così, allora perché non è possibile accedere alla stringa?
Soluzione
strdup assegna una copia della stringa sul heap, che devi liberare manualmente più tardi (con free()
Penso). Se hai l'opzione, sarebbe molto meglio tornare std::string
.
Lo stoccaggio statico di out
non aiuta, perché .str()
Restituisce un temporaneo std::string
, che viene distrutto quando la funzione esce.
Altri suggerimenti
Hai ragione out
è una variabile statica allocata sul segmento di dati. Ma out.str()
è un temporaneo assegnato sullo stack. Quindi quando lo fai return out.str().c_str()
Stai restituendo un puntatore ai dati interni di uno stack temporaneo. Si noti che anche se una stringa non è una variabile dello stack, c_str
è "concesso solo per rimanere invariato fino alla prossima chiamata a una funzione membro non costante dell'oggetto stringa".
Penso che tu abbia colpito una soluzione ragionevole, supponendo che non puoi semplicemente restituire una stringa.
strdup () restituisce un puntatore char* che indica la memoria sul mucchio. Devi liberarlo () quando hai finito, ma sì, funzionerà.
La variabile locale statica std::ostringstream out
Non ha senso in questo caso, a meno che anche la stringa std :: stringa non sia stata statica, che la tua osservazione mostra di non essere vera.
In GetHandStateBrief
, variabile out
non deve essere statico. Hai bisogno di un esplicito static string
per sostituire il temporaneo che veniva creato nella tua chiamata originale a out.str()
:
static std::string outStr;
std::ostringstream out;
... rest of function ...
outStr = out.str();
return outStr.c_str();