Warum wstring nicht :: c_str Ursache ein Speicherleck, wenn nicht richtig gelöscht
-
26-09-2019 - |
Frage
Code-Segment 1:
wchar_t *aString()
{
wchar_t *str = new wchar[5];
wcscpy(str, "asdf\0");
return str;
}
wchar_t *value1 = aString();
Code-Segment 2
wstring wstr = L"a value";
wchar_t *value = wstr.c_str();
Wenn der Wert von Code-Segment 2 nicht gelöscht wird, dann wird ein Speicherverlust tritt nicht auf. wenn Wert1 von Codesegment jedoch 1 wird nicht gelöscht, gibt es einen Speicherverlust. Der interne Code wstring :: c_str sieht gleich zu mir.
Lösung
Eine wichtige Regel. Sie müssen delete
auf etwas verwenden, die von new
erstellt wurde, und Sie müssen nicht löschen etwas anderes
wstr.c_str()
gibt einen Zeiger auf einen Puffer, der wstring
Objekt verwaltet wird. Es wird wieder freigegeben werden, wenn die Zeichenfolge zerstört wird, wonach sich der Zeiger nicht mehr gültig ist. Mit delete
auf das ist falsch. Der Zeiger wird auch für ungültig erklärt werden, wenn Sie die Zeichenfolge ändern.
aString()
gibt einen Zeiger auf einen Puffer, der erstellt wurde new[]
verwenden, so dass Sie es löschen müssen, wenn Sie mit ihm fertig sind (mit delete[]
, new[]
entsprechen). Dies ist fehleranfällig, weshalb es besser Praxis Verwendung ressourcen Verwaltung Klassen (wie string
, wstring
, Container und intelligente Zeiger) anstatt um rohe Zeiger geht und hoffen, dass sie richtig behandelt werden.
Andere Tipps
Da c_str()
kehren Sie einen Zeiger auf die interne Darstellung des wstring
. Die Klasse hält die Kontrolle über die Daten, die er enthält.
Taken from the basic_string::c_str()
Dokumentation von MSDN :
Die zurück C-String sollte nicht sein geändert, da dies ungültig machen könnte der Zeiger auf den String oder gelöscht, wie die Saite hat eine begrenzte Lebensdauer und wird von der Klasse String im Besitz .
Ich werde auf einem Bein gehen und sage, dass ein wstring kein wchar_t ist, sondern eine Klasse, die einen Bediener eines wchar_t * zurück hat, so in dem destructor von wstring, befreit es wahrscheinlich seine eigene Kopie der wchar_t * es gibt.