2011-09-08 42 views
0

試圖解決一個MEM泄漏我已經改變了這一點:斷言試圖刪除一個空對象

void addListener(IListener* listener, const std::string& appender) 
{ 
    std::pair<t_ListenerVectorMap::iterator,bool> p = 
    listenerVectorMap.insert(std::string(appender), new t_ListenerVector); 
    p.first->second->push_back(listener); 

    //add the appender 
    addAppender(appender); 
} 

通過這樣的:

void addListener(IListener* listener,const std::string& appender) 
{ 
    t_ListenerVector* lv = new t_ListenerVector; 
    std::pair<t_ListenerVectorMap::iterator,bool> p = 
    listenerVectorMap.insert(std::string(appender), lv); 

    p.first->second->push_back(listener); 
    if (!p.second) 
    { 
     delete lv; 
    } 

    addAppender(appender); 
} 

我試圖讓乘坐泄漏是新的t_ListenerVector(是一個boost :: ptr_vector)。當appender已經存在於listenerVectorMap中時,插入操作不會修改map的內容,所以新的t_ListenerVector不會被插入,並且會變成mem漏洞。

變化是爲了避免這種泄漏。如果沒有新插入,lv沒有插入,所以我刪除它。但問題是,刪除lv會拋出一個斷言(在vc \ include \ vector Line:70中)。 如果lv沒有改變,爲什麼會出現這個錯誤?

有些想法值得歡迎。 謝謝

+2

你不能「拋出一個說法」。你可以拋出異常,或者斷言失敗。究竟發生了什麼,錯誤是什麼?什麼是定義't_ListenerVector'? –

+0

'lv'不應該失敗,因爲'lv'是指向'new'的指針。 –

+0

使用智能指針'unique_ptr'或'shared_ptr',它既能消除泄漏,又能使代碼異常安全。 –

回答

1

對此回答我假設t_ListenerVectorMap的類型是boost::ptr_map<std::string, boost::ptr_vector<IListener>>。如果不是,那麼這個答案可能是毫無價值的。


您對boost::ptr_map的工作方式存在誤解。確實,您的原始代碼包含內存泄漏,但您的替換代碼更糟糕。 listenerVectorMap.insert(std::string(appender), lv)使listenerVectorMap取得lv的所有權,無論是否插入lv。這意味着delete lv;行會導致雙重刪除。

要修復代碼中的第一個版本的內存泄漏,所有你需要做的是這樣的:

void addListener(IListener* listener, const std::string& appender) 
{ 
    std::auto_ptr<IListener> ls(listener); 
    //The original code leaked here if the std::string constructor threw. 
    std::pair<t_ListenerVectorMap::iterator,bool> p = 
     listenerVectorMap.insert(appender, new t_ListenerVector()); 
    p.first->second->push_back(ls); 

    //add the appender 
    addAppender(appender); 
} 
+0

是的!你的解決方案可以正常工作,但是mem泄漏仍然存在。 – Killrazor

+1

@Killrazor - 1)它是什麼類型的'listenerVectorMap'? 2)爲什麼你認爲這部分代碼有泄漏? 3)你使用的是最新版本的boost嗎? – Mankarse

+0

1.- ListenerVectorMap是boost :: ptr_map 2。 - 我正在玩VLD,一臺泄漏檢測儀。也許我不明白結果,但它將此方法標記爲泄漏。 3-不是最新的,但不是史前的(1.45) – Killrazor

2

做檢查,看它是否存在於地圖第一個,然後調用new來創建該對象。這不一定是錯誤的來源,但這是一種更有效的做法。

+0

+1:絕對好的建議。它也使代碼更具可讀性:) –

0

如果斷言是從你的電話來刪除我會檢查,以確保:

  1. LV是正確初始化。也許它有一個浮點指針,它通過調用delete調用它的析構函數,並使它試圖釋放一點點內存?
  2. 如果插入失敗,它不會爲你清除你的記憶?

關於確切的錯誤報告的一些更具體的信息將會有所幫助。