Почему wstring :: c_str не вызывает утечку памяти, если не удален должным образом - PullRequest
5 голосов
/ 06 августа 2010

Кодовый сегмент 1:

wchar_t *aString() 
{
     wchar_t *str = new wchar[5];
     wcscpy(str, "asdf\0");
     return str;
}
wchar_t *value1 = aString();

Кодовый сегмент 2

wstring wstr = L"a value";
wchar_t *value = wstr.c_str();

Если значение из сегмента кода 2 не удалено, утечка памяти не происходит. Однако, если значение1 из сегмента кода 1 не удалено, происходит утечка памяти. Внутренний код для wstring :: c_str для меня выглядит так же.

Ответы [ 4 ]

11 голосов
/ 06 августа 2010

Важное правило: вы должны использовать delete для всего, что было создано new, и вы не должны ничего удалять.

wstr.c_str() возвращает указатель на буфер, которым управляетwstring объект.Он будет освобожден после уничтожения строки, после чего указатель больше не будет действительным.Использование delete на этом неправильно.Указатель также будет недействительным, если вы измените строку.

aString() возвращает указатель на буфер, который был создан с помощью new[], поэтому вы должны удалить его, когда закончите с ним (используя delete[], чтобы соответствовать new[]).Это подвержено ошибкам, поэтому лучше использовать классы управления ресурсами (например, string, wstring, контейнеры и интеллектуальные указатели), а не передавать необработанные указатели и надеяться, что они обрабатываются правильно.

2 голосов
/ 06 августа 2010

Взято из документации basic_string::c_str() из MSDN :

Возвращенная строка в стиле C не должна быть изменена, поскольку это может сделать недействительнымуказатель на строку или удален, так как строка имеет ограниченное время жизни и принадлежит строке класса .

2 голосов
/ 06 августа 2010

Поскольку c_str() возвращает вам указатель на внутреннее представление wstring.Класс сохраняет контроль над данными, которые он содержит.

1 голос
/ 06 августа 2010

Я собираюсь выйти на конечность и сказать, что wstring - это не wchar_t, а класс, который имеет оператор для возврата wchar_t *, поэтому в деструкторе wstring он, вероятно, освобождает свою собственную копию из wchar_t * он возвращает.

...