Frage

Dies ist aus einer kleinen Bibliothek, die ich online gefunden habe:

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

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

    return out.str().c_str()
}

In meinem Code mache ich das:

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

Jetzt zuerst d Müll enthielt. Ich habe dann festgestellt, dass die C -Zeichenfolge, die ich aus der Funktion bekomme, zerstört wird, wenn die Funktion zurückkommt, weil std::ostringstream wird auf dem Stapel zugewiesen. Also fügte ich hinzu:

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

Und jetzt kann ich den Text erhalten, den ich aus der Funktion brauche.

Ich habe zwei Fragen:

  1. Verstehe ich das richtig?

  2. Das bemerkte ich später out (vom Typ std::ostringstream) wurde mit statischer Speicherung zugewiesen. Bedeutet das nicht, dass das Objekt bis zum Beenden des Programms im Speicher bleiben soll? Und wenn ja, warum kann dann nicht auf die Zeichenfolge zugegriffen werden?

War es hilfreich?

Lösung

StrDUP weist eine Kopie der Zeichenfolge auf dem Haufen zu, die Sie später manuell frei machen müssen (mit free() Ich finde). Wenn Sie die Option haben, wäre es viel besser, zurückzukehren std::string.

Die statische Lagerung von out hilft nicht, weil .str() Gibt eine vorübergehende zurück std::string, was zerstört wird, wenn die Funktion verlässt.

Andere Tipps

Du hast recht out ist eine statische Variable, die im Datensegment zugewiesen ist. Aber out.str() ist eine vorübergehende auf dem Stapel zugewiesene. Also, wenn du es tust return out.str().c_str() Sie geben einen Zeiger auf die internen Daten eines Stapel -Temporary zurück. Beachten Sie, dass auch wenn eine Zeichenfolge keine Stapelvariable ist. c_str wird "nur gewährt, um bis zum nächsten Aufruf einer nicht konstanten Mitgliedsfunktion des String-Objekts unverändert zu bleiben."

Ich denke, Sie haben eine vernünftige Problemumgehung erreicht, vorausgesetzt, Sie können nicht einfach eine Zeichenfolge zurückgeben.

StrDUp () gibt einen Zeichenzeiger zurück, der auf den Speicher auf dem Haufen zeigt. Sie müssen es frei () (), wenn Sie damit fertig sind, aber ja, das wird funktionieren.

Die statische lokale Variable std::ostringstream out in diesem Fall keinen Sinn macht, es sei denn, die zurückgegebene STD :: String war ebenfalls statisch, was Ihre Beobachtung nicht wahr ist.

Im GetHandStateBrief, variabel out muss nicht statisch sein. Sie brauchen einen expliziten static string Um den Temporary zu ersetzen, der in Ihrem ursprünglichen Anruf erstellt wurde out.str():

static std::string outStr;
std::ostringstream out;
... rest of function ...
outStr = out.str();
return outStr.c_str();
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top