2012-10-01 3 views
4

간단한 게임 엔진에는 엔티티에 대한 포인터가 들어있는 벡터가 있습니다. 각 엔티티는 new 키워드로 할당됩니다.벡터의 객체를 올바르게 삭제하는 방법

vector<Entity*>::iterator iter; 
for (iter = gameEntitys.begin(); iter != gameEntitys.end();) { 
    delete (*iter); 
    ++iter; 
} 

하지만 지금은 끔찍한 메모리 누수 모든 프로파일 링 도구 지점이 내 실체에 함수를 호출하기 위해 내가 지금처럼뿐만 아니라 반복자를 사용하는 거라고 나는 반복자를 사용하여 내 엔티티를 삭제할 때 그래서 나는 생각 라인쪽으로 delete (*iter);

명백하게 뭔가 잘못되었지만 벡터에 포함 된 엔티티를 삭제하고 다른 장면의 벡터를 지우는 올바른 방법은 무엇입니까? gameEntitys.clear();을 사용하면 실제 데이터가 아니라 포인터이기 때문에 벡터에서 실제로 delete를 호출하지 않는 요소 만 제거하므로 유용하지 않습니다.

편집 : 나는 의견을 보았습니다. Entity 클래스는 다형성이 아니며 하위 클래스가 없습니다. 동적 메모리 사용을 중단하고 포인터가 아닌 엔티티 배열이 정상적인 경우 더 유용할까요?

메모리 누수가있는 이유는 응용 프로그램이 시작될 때 메모리 사용이 충돌하기 전에 최대 2GB까지 촬영하기 때문입니다.

+4

이것은 'unique_ptr'이 무엇을위한 것입니까? – dasblinkenlight

+0

어떻게 메모리 누수가 있다고 판단 했습니까? 표시 한 코드는'gameEntitys' 객체에있는 모든 포인터를 삭제합니다. 그 일을 한 후에는 물론 '취소'해야합니다. –

+0

그리고 하나의 'Entity'를 삭제하고 메모리 누수를 확인 했습니까? – Beta

답변

7

대부분의 경우 메모리 누수는 Entity 또는 해당 하위 클래스 중 하나의 소멸자에서 발생합니다. 즉, delete 작업을 올바르게 수행하고 있으므로 소멸자 자체에 결함이 있어야합니다. 일반적인 문제 중 하나는 다형성 클래스 계층 구조에서 소멸자를 가상으로 만드는 것이 아닙니다.

gameEntitys.clear()의 쓸데없는 점에 대해서도 절대적으로 옳습니다. 참조를 "잊어 버리면" "물체가 새어 나옵니다". 당신이 C++ 11에있는 경우 개체에 대한 포인터를 유지시키는 동안

,이 수동으로 항목의 메모리를 관리 할 필요성에서 당신을 해방합니다 std::unique_ptr

std::vector<std::unique_ptr<Entity> > gameEntitys; 

를 사용하도록 정의를 변경 고려 귀하의 vector에서 파생 된 수업의 unique_ptr을 사용하는 경우 gameEntitys.clear()을 호출하면 벡터의 요소가 가리키는 항목이 삭제됩니다.

unique_ptr의 벡터 처리는 다소 다릅니다 (예 : 새 항목을 삽입하려면 특별한주의가 필요함, 자세한 내용은 this answer 참조). 단순화 된 메모리 관리의 장점은 약간의 불편 함을 보상한다고 생각합니다.

편집 : 당신의 Entity 클래스 다형성하지 않기 때문에, 당신이 나중에 다형성 계층 구조로 전환 할 계획이 아니라면, std::vector<Entity>로 전환하는 것이 좋습니다.

+0

이렇게하면 벡터에 액세스하는 구문이 변경됩니다. 암묵적인 변환이 없기 때문에 그는'Entity * '를 직접 읽을 수 없습니다. 그리고 그는 확실히'std :: unique_ptr '을 읽는 것을 원하지 않습니다, 왜냐하면 이것은 벡터에서 데드 포인터가 될 것이기 때문입니다. –

+0

@JamesKanze 메모를 주셔서 감사 드리며, 나는 'std :: unique_ptr '이 드롭 인 대체품이 아니라는 답변을 변경했습니다. 고마워요! – dasblinkenlight

+0

+1. C++ 11과 std :: unique_ptr을 사용할 수 없다면 같은 방식으로 boost_upr을 사용할 수 있지만 벡터가 수정되면 ref 카운팅에 약간의 오버 헤드가 있습니다. –

관련 문제