CppUtest發現的STL容器內存泄漏問題 頂 原 薦

今天在給代碼做UT時,某個case 中報出有內存泄露,提示信息可以看出泄漏的大小但沒有具體位置。定位問題的方法不再細述,主要是通過縮減代碼,逐步定位泄露地點。事後爲了便於說明問題,寫了兩個小巧的case,你能從下面兩個case中看出哪個存在內存泄露嗎?

std::string g_leak_str; // 定義一個全局string 變量
...
TEST(mt_adaptor, leak01)
{
   g_leak_str = "Hello World!";
   g_leak_str.clear();
}


TEST(mt_adaptor, leak02)
{
   g_leak_str = "Hello World!";
   std::string().swap(g_leak_str);
}

答案是case01存在內存泄露。錯誤提示信息如下:

../../tst/src/mt_adapt.cpp:232: error: Failure in TEST(mt_adaptor, leak01)
     Memory leak(s) found.
Alloc num (6194) Leak size: 37 Allocated at: <unknown> and line: 0. Type: "new"
     Memory: <0xedbf10> Content: ""
Total number of leaks:  1

其實問題的關鍵是STL中內存分配策略及回收策略,具體參考《C++ Primer》,這裏簡單提一下,當爲string變量賦值時,如果該變量內存不夠會觸發malloc爲該變量分配更多的內存,也就是錯誤提示中提到的“new”。clear()方法只是把存儲內容清空,已經存在的內存不會釋放,這也就是CppUTest認爲存在內存泄漏的原因,即CppUTest在該case結束時發現堆空間變小了。case leak02所示方法,通過與一空匿名string變量交換,也實現了內存釋放。待case結束時匿名string也會自然消亡,所佔內存也會釋放,所以沒有問題。 


這裏以string對象舉例,STL中定義的其他容器也有類似的問題。

補充一句,這種情況不是嚴格意義上的內存泄漏,因爲內存還在管控之中,但是在用完某個對象後將其恢復原樣永遠沒錯。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章