簡體   English   中英

調用vector.erase()時出現分段錯誤

[英]Segmentation fault when calling vector.erase()

每當我調用std::vector<Domino>類型的dominoes.erase() ,都會遇到分段錯誤; 即使我將值硬編碼。

一個單獨的成員函數調用dominoes.push_back()加載數據,並且我可以使用pop_back()從向量中刪除並返回一個Domino,所以我知道其中有數據。 我已經在Domino對象上制作了一個復制構造函數,並且效果很好。 我將其范圍縮小到dominoes.erase()

Domino::Domino( const Domino &d ) {
    left = d.getHighPip();
    right = d.getLowPip();

}
Domino DominoCollection::drawDomino( void )
{

    int index = random.nextNumber( dominoes.size()  );
    Domino d( dominoes[index] );
    dominoes.erase( dominoes.begin() + index );

    return Domino( d );
}

任何幫助將不勝感激。 謝謝!

嘗試通過刪除所有不必要的代碼(對象復制,向量訪問...)來縮小錯誤的范圍。 然后,如果問題確實來自erase ,請添加保護措施以確保索引正確。 嘗試使用以下代碼:

#include <cassert>
void DominoCollection::drawDomino( void )
{
    assert(dominoes.size() != 0 && "Your vector is empty");
    int index = random.nextNumber( dominoes.size()  );
    assert(index < dominoes.size() && "Buffer overflow...");
    dominoes.erase( dominoes.begin() + index );
}

如果仍然存在段錯誤,則問題出自類Domino的析構函數。 看看那里是否有魚。 您可以通過注釋析構函數的一部分(或全部)來進行快速測試,以了解問題的根源。 調用erase將調用Domino的析構函數。

如果未實現析構函數,則最好在其中實現一個帶有輸出(在cerr ,而不是cout )的析構函數,以了解它是否到達那里或更早崩潰。 Domino是派生類嗎? 它是否包含其他任何對象或僅包含原始類型的組合?

編輯

我快速瀏覽了您的代碼:問題來自賦值運算符:

Domino & Domino::operator = ( const Domino & d )
{
    *this = d;
}

不是應該怎么寫的...我讓您調試一下作為練習。

至於為什么這是錯誤的根源:您說的是erase崩潰,但不是pop_back 兩者之間的主要區別(實現上的區別,不是明顯的語義上的區別)在於,刪除操作會導致所有元素在刪除后(使用=運算符)發生移位,因為std::vector要求元素連續存儲。 而pop只會更改尾指針,而不會更改容器的其余部分。

根據您的顯示,看來int index的值大於或等於dominoes.size() 否則,該代碼將正常工作。

我會檢查random.NextNumber(dominoes.size())返回什么。

另外,如果dominoes.size() == 0則可能會出現此問題。 在這種情況下,您將要擦除dominoes.end()

暫無
暫無

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

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