[英]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.