2012-01-11 40 views
1

我一直試圖調試這個差不多半天,現在我似乎無法找到問題。最有可能是什麼原因造成的麻煩是這種方法:std ::列表刪除導致問題的元素

//[datamember]  
std::list<Projectile*> m_Projectiles_l; 

//[predicate]  
bool removeDeads(Projectile* pProj) { 
    return !(pProj->isAlive()); 
} 

//[the method I think might be causing the problem] 
void ProjectileList::KillDeadProjectiles() 
{ 
    std::list<Projectile*>::iterator it; 
    it = std::remove_if(m_Projectiles_l.begin(), m_Projectiles_l.end(), &removeDeads); 

    if (it != m_Projectiles_l.end()) 
    { 
     std::list<Projectile*>::iterator itDelete; 
     for (itDelete = it; itDelete != m_Projectiles_l.end(); ++itDelete) { 
      delete (*itDelete); 
     } 
     m_Projectiles_l.erase(it, m_Projectiles_l.end()); 
    } 
} 

VS2010破錯誤:

Unhandled exception at 0x00389844 in PsychoBots.exe: 0xC0000005: Access violation reading location 0xfeeeff3a. 

最新使我這一行:

void ProjectileList::DoPhysicsStuff(const InputState& refInputState) 
{ 
    KillDeadProjectiles(); 

    std::list<Projectile*>::iterator it; 
    for (it = m_Projectiles_l.begin(); it != m_Projectiles_l.end(); ++it) { 
/*[THIS line]*/(*it)->DoPhysicsStuff(refInputState); 
    } 
} 

我的發現:

It gives a problem when: there are more than 2 elements in the list, and a "projectile that has been added to the list earlier than a projectile that has been added later on" is getting removed with this method.

It gives no problems when: There is only one element in the list OR All the elements are getting removed at the same time.

任何人都可以看到任何錯誤在這?

如果您需要更多的代碼請評論,我現在試圖保持它的小尺寸。

+3

您不允許使用經過'remove_if'結果的迭代器。你可以擦除它們,但是你不能訪問它們,因爲它們不能保證處於任何特定的狀態。儘管如此,您可以省去所有這些浪費時間,並停止使用原始指針。 – 2012-01-11 15:24:59

+0

@KerrekSB我幾乎加入了評論「請不要評論智能指針」,因爲我不允許使用它們;)但是我決定不這樣做,因爲人們喜歡對它進行評論。 – xcrypt 2012-01-11 15:30:28

回答

2

您不能依賴於容器的內容,而不是由remove_if返回的迭代器。這意味着如果你想管理容器中的動態內存,你將不得不採取不同的方法。簡單的方法是存儲shared_ptr對象而不是原始指針。然後,你可以使用刪除 - 刪除成語,一切都將被清理。否則,你需要仔細寫下刪除機制,而不是使用remove_if

1

請仔細閱讀std :: remove_if()的引用。 (http://www.cplusplus.com/reference/algorithm/remove_if/)

範圍「it」到「m_Projectiles_l.end()」中的值仍然有效,但其值未指定。這些值很可能不會改變,具體取決於實施情況。

這樣一個元素可以被包含在新列表中,並且仍然在舊列表的末尾。刪除此元素將導致內存異常。

你必須找到另一種方法來刪除不再引用的元素。考慮智能指針。

+0

是的,我應該確定。下次更好的閱讀參考:) – xcrypt 2012-01-11 15:43:57