2013-03-13 2 views
0

클래스가 Bar이고 생성자가 Foo (다른 클래스) 인 std::vector으로 초기화됩니다.메모리 누수, 벡터 푸시 백 C++

Bar.cpp

Bar::Bar(int n) { 
for(int i = 0; i < n; i++) { 
    Foo foo; 
    foo.somefunction(i); 
    vec.push_back(foo) //this should insert foo into the vector 
    } 
} 

Bar.h

class Foo; 
class Bar { 
std::vector<Foo> vec; 
}; 

내가 디버깅 할 때, 공사의 첫 번째 반복은 잘 작동합니다. foo이 생성되고 foo.somefunction()은 정상적으로 실행되고 foovec에 푸시됩니다.

두 번째 인터리브는 잘 작동하는 것처럼 보이지만 프로그램이 세 번째 반복을 시작하기 위해 돌아 가면 충돌이 발생합니다.

_BLOCK_TYPE_IS_VALID(pHead->nBlockUse) 오류 및 HEAP CORRUPTION DETECTED이 표시됩니다.

Foo은 동적으로 생성 된 배열을 포함하는 클래스입니다. 특별한 것은 없습니다. 이 같은 뭔가 :

Foo::Foo() { 
    solution = new float[size]; 
    // some function that initializes the elements of solution 
} 

하고 정기적 소멸자 ~Foo() {delete [] solution;}. 문제가 Foo에서 발생한다고 생각하지 않습니다.

+2

아마도 3 개의 규칙. – chris

+4

당신은'Foo'의 벡터를 사용했습니다. 왜 '플로트'벡터를 사용하지 않았을까요? 너에게 문제가 마술처럼 사라질거야. – jrok

+0

이 방법으로 float 벡터를 선언 해 보았습니다. std :: vector vec (size); 하지만 작동하지 않습니다. 런타임에 결정된 크기의 벡터를 선언하는 방법은 무엇입니까? – jazzybazz

답변

4

대부분 copy constructoroperator =을 올바르게 구현하지 않았으므로 solution을 두 번 삭제 중입니다. 언급했듯이 The Rule of Three에서 읽어야합니다.

C++ 표준 컨테이너 store copies이므로 push_back을 작성하면 복사본이 만들어집니다.

+0

고맙습니다. 동적 배열을 없애고 대신 float 벡터를 사용한다고 생각합니다. – jazzybazz

+0

@jazzybazz 아마도 가장 간단한 해결책 일 것입니다. –

0

Foo 클래스에 복사 생성자를 구현하지 않은 것 같습니다. Bar 생성자에서 Foo의 모든 반복 인스턴스는 반복이 끝나면 만들어지고 파기됩니다. 그래서 Foo에 할당 된 메모리는 파괴되지만 Foo의 인스턴스를 벡터에 복사 한 기본 복사 생성자는 "new"로 할당 한 메모리를 복사하지 않고 포인터를 복사하기 만하면됩니다. 따라서 각 반복 후에 각 벡터 요소가 손상됩니다. 벡터가 처음에 객체에 할당 된 메모리를 가지고 있다고 가정 해 봅시다. 그런 다음 버퍼에 공간이 없으면 버퍼를 더 이상 확장 할 수 없으므로 벡터는 새 메모리를 할당하고 다른 복사 작업이 수행됩니다. 복사 작업이 완료되면 이전 버퍼를 해제해야하고 벡터는 이전 버퍼의 모든 객체를 파괴하고 각 객체의 소멸자는 손상된 포인터에서 delete []를 호출합니다.