2015-03-31 109 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