2012-11-26 18 views
1

我得到了這個不完整的測試用例的內存泄漏報告。如果我傳遞「nameNameNameNam」,那麼就沒有泄漏報告。當std :: string size> = 16時出現內存泄露

TEST_F (TestDoesExist, namePassedToCInterface) 
{ 
    Accessor accessor(_cInterface, _handle); 
    accessor.doesExist(std::string("nameNameNameName")); 
} 

下的代碼測試看起來是這樣的:

virtual bool doesExist(const std::string& name) 
{ 
    bool result; 
    _cInterface.exists(_txHandle, name.c_str(), &result); 
    return result; 
} 

到C接口的調用如下嘲笑:

class MockDoesExist 
{ 
public: 
    MockDoesExist() { 
     handle=Handle(); 
     name = ""; 
     result = true; 
    } 

    static void func(Handle _handle, const char* _name, bool* _result) { 
     // in values 
     handle = _handle; 
     name = _name; 

     // out values 
     *_result = result; 
    } 

    // in values 
    static Handle handle; 
    static std::string name; 
    // out values 
    static bool result; 
}; 
Handle MockDoesExist::handle; 
std::string MockDoesExist::name; 
bool MockDoesExist::result; 

我用VS 2010速成comiling。

我:

_CrtMemCheckpoint(&memAtStart); 

測試用例執行前:

_CrtMemDifference(&memDiff, &memAtStart, &memAtEnd) 

後。

我在做什麼錯?

+2

15個字符的限制可能是由於std :: string類中的「小字符串優化」(對於小字符串數據存儲在成員數組中,沒有動態分配任何內容)。 –

+0

一個可能的技巧是三次運行你的測試,並將報告的分配不是3的倍數作爲調查的低優先級(因爲它可能不是持久性泄漏)。一個可能的解決方法是在調用'_CrtMemDifference'之前繁瑣地清理靜態變量。例如,'std :: string()。swap(MockDoesExist :: name);'。 –

回答

10

沒有。 _CrtMemDifference在測試用例之後被調用,但之前MockDoesExist的靜態成員被破壞(它們在程序終止之前被破壞)。在您的測試案例中,MockDoesExist::name被分配您的長字符串。在MSVC的標準庫中,有一個針對短字符串的優化,意味着每個std :: string都有一個內部16字節的字符數組,其中可以存儲較短的字符串。只有更長的字符串,它必須從免費商店分配內存。該內存將在字符串的析構函數中釋放,在這種情況下MockDoesExist::name被破壞,即_CrtMemDifference被調用後。

0

我不認爲你做錯了什麼。一旦MockDoesExist::name被破壞,報告的「內存泄漏」將消失。