2012-01-11 3 views
1

저는 거의 반나절 동안 이것을 디버깅하려고 노력해 왔지만 문제를 찾을 수없는 것 같습니다.std :: list 문제를 일으키는 요소를 삭제했습니다.

//[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'의 결과를 따라 반복기를 사용할 수 없습니다. 지울 수는 있지만 특정 상태에있을 수는 없으므로 액세스하지 않아야합니다. 그래도 시간 낭비를 모두 감수하고 원시 포인터 사용을 중단하십시오. –

+0

@KerrekSB 필자는 "스마트 포인터에 대한 코멘트가 없다"고 덧붙였다. 왜냐하면 사람들은 그것을 사용하기를 좋아하기 때문에 그렇게하지 않기로 결정했다. – xcrypt

답변

2

remove_if이 반환 한 반복기를 넘어선 컨테이너의 내용에 의존 할 수 없습니다. 즉, 컨테이너의 동적 메모리를 관리하려면 다른 접근 방식을 취해야합니다. 쉬운 방법은 원시 포인터 대신 shared_ptr 객체를 저장하는 것입니다. 그런 다음 제거 삭제 관용구를 사용하면 모든 것이 정리됩니다. 그렇지 않은 경우 remove_if 대신 신중하게 제거 메커니즘을 작성해야합니다.

1

std :: remove_if() 참조를주의 깊게 읽으십시오.

범위 "it"에서 "m_Projectiles_l.end()"까지의 값은 여전히 ​​유효하지만 그 값은 지정되지 않습니다. 대부분의 경우 해당 값은 구현에 따라 변경되지 않습니다.

이렇게하면 요소가 새 목록에 포함되어 여전히 이전 목록의 끝에있을 수 있습니다. 이 요소를 삭제하면 메모리 예외가 발생합니다.

더 이상 참조되지 않는 요소를 삭제하는 다른 방법을 찾아야합니다. 스마트 포인터를 고려하십시오.

+0

예. 나는 피해야한다. 더 나은 다음 번에 참조 읽기 :) – xcrypt

관련 문제