2015-03-31 124 views
-1

在专有应用程序的开发过程中。我已经注意到了内存泄漏,到std ::相关字符串在微软的Visual C++ 2013,更新4Visual C++ 2013 std :: string内存泄漏

看看下面的(基本)代码的原型导致内存泄漏:

static std::string MemoryLeakTest() 
{ 
    static size_t const test_size = 2002; 
    std::unique_ptr<char[]> result1(new char[test_size]); 
    std::string result2(result1.get(), test_size); 
    return result2; 
} 

通话它通过:

std::string const testML = MemoryLeakTest(); 
std::cout << testML << std::endl; 

我做错了什么,或者它是在Visual C++ STL内存泄漏?

P.S.这是表示MEM渗透通过VLD检测DebugView中输出:

[11140] WARNING: Visual Leak Detector detected memory leaks! 
[11140] ---------- Block 3 at 0x00A95620: 2002 bytes ---------- 
[11140] Leak Hash: 0x1DA884B6, Count: 1, Total 2002 bytes 
[11140] Call Stack (TID 9568): 
[11140]  0x0FF5C260 (File and line number not available): MSVCR120D.dll!operator new 
[11140]  f:\dd\vctools\crt\crtw32\stdcpp\newaop.cpp (6): TestCpp.exe!operator new[] + 0x9 bytes 
[11140]  c:\work\testcpp\testcpp.cpp (307): TestCpp.exe!MemoryLeakTest + 0xA bytes 
[11140]  c:\work\testcpp\testcpp.cpp (401): TestCpp.exe!wmain + 0x9 bytes 
[11140]  f:\dd\vctools\crt\crtw32\dllstuff\crtexe.c (623): TestCpp.exe!__tmainCRTStartup + 0x19 bytes 
[11140]  f:\dd\vctools\crt\crtw32\dllstuff\crtexe.c (466): TestCpp.exe!wmainCRTStartup 
[11140]  0x75557C04 (File and line number not available): KERNEL32.DLL!BaseThreadInitThunk + 0x24 bytes 
[11140]  0x77C4B54F (File and line number not available): ntdll.dll!RtlInitializeExceptionChain + 0x8F bytes 
[11140]  0x77C4B51A (File and line number not available): ntdll.dll!RtlInitializeExceptionChain + 0x5A bytes 
[11140] Data: 
+0

你怎么知道它是std :: string导致泄漏? – 2015-03-31 15:03:55

+3

您的代码具有未定义的行为,因为您正在读取未初始化的值。 – 2015-03-31 15:10:15

+0

你是怎么确定这个代码泄漏的? – Casey 2015-03-31 15:58:06

回答

0

尝试与Deleaker的代码,它找不到任何泄漏。

然后尝试这种代码:

while (true) 
{ 
    std::string const testML = MemoryLeakTest(); 
    std::cout << testML << std::endl; 
} 

任务管理器显示内存使用情况是一样的:没有泄漏。

我觉得这是在VLD一个bug,你可以找到的std ::真正的unique_ptr释放内存,调试期间刚刚踏入,请看:

~unique_ptr() _NOEXCEPT 
    { // destroy the object 
    _Delete(); 
    } 

走得更远:

void _Delete() 
    { // delete the pointer 
    if (this->_Myptr != pointer()) 
     this->get_deleter()(this->_Myptr); 
    } 
}; 

继续:

void operator()(_Ty *_Ptr) const _NOEXCEPT 
    { // delete a pointer 
    static_assert(0 < sizeof (_Ty), 
     "can't delete an incomplete type"); 
    delete[] _Ptr; 
    } 
}; 

啊哈,删除[]被称为!

+0

是的,我的最终结论是一样的 - 这可能是VLD中的一个错误。非常感谢您的时间和分析。 – 2015-04-01 10:28:44

0

呼叫

std::unique_ptr<char[]> result1(new char[test_size]); 

是正确的。棘手的部分是不写std::unique_ptr<char>,它也编译并可能导致内存泄漏(unique_ptr调用delete释放资源。当使用new[]初始化时,我们需要指示unique_ptr调用正确的delete[])。

std::string构造函数调用也可以,并且不太可能存在内存泄漏。 std::string可以用相同的方式从C风格的指针初始化。

我在代码片段中没有看到任何内存泄漏。你怎么知道这是内存泄漏?

+0

这不再是真的吗?最新的标准自动处理shared_ptr和unique_ptr中的数组删除操作。 – Robinson 2015-03-31 16:12:59

+0

@Robinson恰好,MSDN文档: (A部分特的unique_ptr 管理与新[]数组分配对象,并且具有默认的删除器default_delete ,专门调用删除[] _Ptr。) HTTPS:// MSDN .microsoft.com/en-us/library/ee410601.aspx – 2015-03-31 16:17:04

+0

还在挠挠我的脑袋,关于std :: unique_ptr 和std :: unique_ptr 之间的区别。我想他们编译到相同的东西,或者后者有效地指向一个指针?这会让它破裂(但它不适合我)。 – Robinson 2015-03-31 16:18:24