为什么wstring :: c_str如果没有正确删除就会导致内存泄漏

时间:2010-08-06 14:55:39

标签: c++ multibyte widestring wstring

代码段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中的value1,则会发生内存泄漏。 wstring :: c_str的内部代码对我来说是一样的。

4 个答案:

答案 0 :(得分:11)

一条重要规则:您必须对delete创建的任何内容使用new,并且不得删除任何其他内容。

wstr.c_str()返回指向由wstring对象管理的缓冲区的指针。当字符串被销毁时,它将被释放,之后指针将不再有效。在此使用delete是错误的。如果修改字符串,指针也将失效。

aString()返回指向使用new[]创建的缓冲区的指针,因此您必须在完成后使用delete[]将其删除,以匹配new[] })。这很容易出错,这就是为什么更好的做法是使用资源管理类(如stringwstring,容器和智能指针),而不是传递原始指针并希望它们得到正确处理

答案 1 :(得分:2)

因为c_str()会返回指向wstring的内部表示的指针。该类控制着它所包含的数据。

答案 2 :(得分:2)

取自basic_string::c_str() documentation from MSDN

  

返回的C风格字符串不应该   被修改,因为这可能会失效   指向字符串的指针,或已删除,   因为字符串的寿命有限   并且由类字符串拥有。

答案 3 :(得分:1)

我打算说一个wstring不是wchar_t,而是一个有一个运算符返回wchar_t *的类,所以在wstring的析构函数中,它可能会释放自己的副本它返回的是wchar_t *。