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存在內存泄露。錯誤提示信息以下: spa

../../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也會天然消亡,所佔內存也會釋放,因此沒有問題。  code


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

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

相關文章
相關標籤/搜索