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