2013-12-11 41 views
1

此代碼的工作:我如何錯誤地使用矢量迭代器?

for (unsigned int i = 0; i != m_cResources.getLoadedPlayers().size(); i++) { 
    m_cResources.getLoadedPlayers()[i]->update(); 
} 

當我嘗試使用迭代器與下面的代碼,我的程序掛起並停止工作:

for (std::vector<CPlayer*>::iterator i = m_cResources.getLoadedPlayers().begin(); 
     i != m_cResources.getLoadedPlayers().end(); i++) { 
    (*i)->update(); 
} 

getLoadedPlayers()返回CPlayer的矢量*。更新是CPlayer中的成員函數。

我從來沒有使用迭代器之前,所以我真的不知道什麼是錯的。我不認爲這個錯誤不在這個代碼之外,因爲第一個塊可以工作。所以我假設我的迭代器的實現是錯誤的。有任何想法嗎?

編輯:getLoadedPlayers()返回由值的矢量,而不是參考。這很可能是問題嗎?但那麼第一個代碼塊也不行?我會盡快對此進行測試。

更新函數基於先前設置的標誌在CPlayer修改成員值。

+2

「CPlayer :: update」中是否修改了由'getLoadedPlayers()'返回的向量(並因此可能使迭代器失效)? –

+1

和樣式註釋:更喜歡用'++ i'作爲迭代器到'i ++'。 –

+3

'getLoadedPlayers'是否通過引用或按值返回向量? –

回答

2

如果如你所說getLoadedPlayers(),因爲在每次迭代中的載體的新的副本中的表達被用來返回由值的矢量,不引用則第一循環也沒有意義

m_cResources.getLoadedPlayers()[i]->update(); 

當在循環

for (std::vector<CPlayer*>::iterator i = m_cResources.getLoadedPlayers().begin(); 
     i != .getLoadedPlayerm_cResourcess().end(); i++) 

然後迭代器使用迭代i和getLoadedPlayerm_cResourcess()。端()指向differenent存儲器程度。所以他們可能不會被比較。

如果你想你的循環了,你應該使用參考原始矢量任何意義。

2

爲什麼不使用C++的每個?

for (auto &i : m_cResources.getLoadedPlayers()) { 
    i->update(); 
} 
+0

如果問題是按值返回的,並且update()是爲了在對象中產生持久效果,那麼上述方法將不能解決實際問題。 –

+2

不錯的建議。小挑剔:vector的元素本身就是指針,所以它應該是'i-> update();'。 – pyon

+0

當然,它確實需要C++ 11支持,但不幸的是,它並不是無處不在。 –

1

您的載體是通過返回值,所以你的迭代時遞增循環的每次迭代將永遠「滿足」的循環退出條件結束迭代器:它屬於另一個向量(在每次迭代改變)。 因此,您的代碼通過取消引用無效迭代器(以及基礎指針)來調用未定義的行爲。