簡體   English   中英

C ++映射具有在退出時自動釋放的指針,如何處理刪除

[英]C++ map with pointers that are automatically freed upon exit, how to handle delete

我有一個使用字符串作為鍵和使用自定義對象的指針作為值的映射。 在運行時,用戶可以創建該對象(指針)的實例,該實例自動添加到地圖中。 我使用DrMemory來查看是否有泄漏(例如內存泄漏)。

因此,我測試該應用程序時沒有手動刪除包含映射的指針,也沒有發現錯誤(因此也沒有發現內存泄漏)。 為了安全起見,我還對退出方法進行了測試,該方法在退出該程序時會反復遍歷地圖並手動刪除每個指針。

現在,當我對其進行測試時,我會遇到幾種相同的錯誤:

無法訪問已釋放的內存...

發生的線是指向清理方法的位置。

我現在的問題是:我應該保留對清除方法的調用(因此只需忽略錯誤),還是應該刪除調用並保留該調用,因為它知道沒有必要手動刪除指針?

我正在刪除指針並從地圖中刪除條目

void cleanUp(std::map <string, Car*>* map){
    for(auto const& x : *map){
       delete x.second;
        map->erase(x.first);
    }
}

很難看到它,而不會看到源代碼,但是在任何地方都保留指向動態分配對象的裸指針(不受RAII實現類保護的指針)是不良做法的標志。 學習使用智能指針,您將不需要使用任何內存泄漏檢測器,確實可以用C ++編寫代碼而不必擔心內存泄漏,例如使用unique_ptr的示例代碼:

std::map<std::string, std::unique_ptr<std::string>> mm;
mm["alpha"] = std::make_unique<std::string>("alpha");

您的循環是錯誤的。 基於范圍的for循環等效於使用迭代器在地圖上進行迭代,但是當您刪除當前使用的元素時,迭代器將變為無效。 (獲取下一個元素的++操作將嘗試使用已釋放的鏈接或其他任何鏈接)。

相反,您可以這樣寫:

for(auto const& x : *map){
    delete x.second;

map->clear();

這可能會更有效,因為它可以快速刪除整個地圖,但是一次刪除一個項目較慢。

注意 考慮在地圖中使用智能指針,以便在清除地圖時自動釋放項目。

不,忽略這些錯誤是不明智的。 您大概是在使用DrMemory來查找代碼問題,所以為什么忽略它? 僅僅因為您的程序運行正常並不意味着就可以了。 您的代碼中很有可能存在未定義的行為。 它似乎可以正常工作,巧妙地損壞或崩潰。 而且,當程序發布給用戶時,您絕對不希望其崩潰。

您應該從地圖中刪除包含無效指針的項目,或者最好使用智能指針。 但是,包含指針值的映射似乎有點像反模式。 考慮一下:

map[1] = new Foo();
map[1] = new Foo(); // Oops, you're now leaking memory!

您將如何刪除以前的Foo()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM