簡體   English   中英

無法刪除指針的向量

[英]Having trouble deleting vector of pointers

我有一個管理器類,它包含一個指向虛擬基類的指針向量,允許在那里存儲各種子類。 在這個管理器類的析構函數中,我希望它循環遍歷它所擁有的所有指針並刪除它們。 但是,我嘗試了許多方法,程序在執行過程中不斷崩潰。

我現有的代碼如下所示: -

for (std::vector<GameState*>::iterator it = gamestates_.begin(); it != gamestates_.end(); ++it){
    delete *it;
    it = gamestates_.erase(it);
}

我還沒有嘗試過的一件事是使用unique_ptr,但我確信這應該能夠在不使用它們的情況下處理它。 如果我錯了,請糾正我。

編輯:我知道我應該在循環之后清除向量,但這是我在嘗試刪除指針的每個常規方法后所得到的。 它似乎不喜歡刪除命令。

從向量中刪除元素會使迭代器無效,因此您無法繼續迭代。 在這種情況下,我不會擦除循環中的元素; 之后我會清除矢量:

for (auto it = gamestates_.begin(); it != gamestates_.end(); ++it){
    delete *it;
}
gamestates_.clear();

雖然,如果這是在析構函數中並且矢量即將被銷毀,那么也沒有必要清除它。

如果你確實需要在循環中擦除(也許是因為你只想刪除一些元素),那么你需要更加小心以保持迭代器有效:

for (auto it = gamestates_.begin(); it != gamestates_.end();){ // No ++ here
    if (should_erase(it)) {
        it = gamestates_.erase(it);
    } else {
        ++it;
    }
}

我還沒有嘗試過的一件事是使用unique_ptr但我確信這應該能夠在不使用它們的情況下處理它。 如果我錯了,請糾正我。

如果你確實希望通過蒸汽管理動態對象,那么請確保遵循規則三 :你需要實現(或刪除)復制構造函數和復制賦值運算符,以防止“淺”復制離開你兩個試圖刪除相同對象的向量。 您還需要注意刪除刪除或替換它們的任何其他位置的對象。 存儲智能指針(或者對象本身,如果你不需要多態性的指針)將為你處理所有這些事情,所以我總是建議這樣做。

我知道我應該在循環之后清除向量,但這是我在嘗試刪除指針的每個常規方法之后所得到的。 它似乎不喜歡刪除命令。

最可能的原因是您沒有遵循三規則,並且在復制矢量后意外地嘗試刪除兩次相同的對象。 GameState也可能是一個基類,你忘了給它一個虛擬析構函數,或者指針已經被其他代碼破壞了。

您的迭代器在每個循環中更新兩次:

it = gamestates_.erase(it);

it++

你只需要第一個 - 它已經指向容器中的“下一個對象”。

從向量中刪除元素會使迭代器無效。 按元素刪除對象指針,然后clear()向量的內容。

擺脫你的for循環標題中的++it

erase已經為你進步了。

或者,迭代,刪除,然后迭代.clear()

更喜歡使用unique_ptr 你說你應該能夠在不使用它們的情況下處理它 ,好像獲得一個智能指針為你做的工作是某種可怕的強加。

他們在那里讓你的生活更輕松,你不必因為不用手工做而感到內疚。

使用現有代碼,只需不要調用erase 無論如何,矢量將被摧毀,對吧? 它會照顧好自己。

問題是,你正在增加it的兩倍。 首先,當你調用it = .erase(it)返回下一個元素,然后在循環++i 你可能無意中跳過了最后,事情可能會出錯,更不用說你只會刪除你向量的每一個元素。

一個簡單的解決方法就是不要在循環中改變it (沒有++it )。

更好的方法是從向量的末尾實際刪除數組,因為向量內部的擦除元素引入了所有后續元素的昂貴移動。 您當前的算法將在N^2時間內工作。 嘗試這樣的事情:

while (!gamestates_.empty()) {
    delete gamestates_.back();
    gamestates_.erase(gamestates_.end()-1);
}

您也可以迭代向量的所有元素並在之后清除它:

for (std::vector<GameState*>::iterator it = gamestates_.begin(); it != gamestates_.end(); ++it){
    delete *it;
}
gamestates_.clear();

另請注意,向量的clear()操作也在其析構函數中完成。 如果刪除過程是某些銷毀過程的一部分,其中gamestates_被極度破壞 - 您根本不必調用clear()

暫無
暫無

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

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