2012-07-03 1 views
1

연습 문제가 발생하며 메모리 누수가 없는지 확인하기 위해 소멸자를 만들어야합니다. 나는이 소멸자를 사용하는 경우, 내가 ("일시 중지") 시스템을 실행 한 후,이 오류를 얻고있다 ;:클래스 소멸자 오류

여기 http://imgur.com/r2bvF

는 복사 생성자입니다 :

vector_of_int::vector_of_int (const vector_of_int& a_vector) 
    { 
     an_array = new int[ a_vector.size ]; 

     this->size = a_vector.size; 
     for(int i = 0; i < size; ++i) 
     { 
      an_array[i] = a_vector.an_array[i]; 
     } 
    } 

및 할당 연산자 :

vector_of_int& vector_of_int::operator= (const vector_of_int& a_vector) 
    { 
     if(this == &a_vector) 
     { 
      return *this; 
     } 

     this->size = a_vector.size; 
     for(int i = 0; i < size; ++i) 
     { 
      an_array[i] = NULL; 
      an_array[i] = a_vector.an_array[i]; 
     } 
      return *this; 
    } 

나는 온라인으로 약간의 검색을했는데, 동일한 메모리 위치를 가리키는 복사 생성자 때문일 수 있다고 언급했다. 이것을 테스트하기 위해 main() 함수에서 각 벡터 a, b, c에 데이터를 푸시하고 다시 인쇄하여 모두 다르게 표시했습니다. 이 오류는 소멸자가 호출되고 다음 라인 시스템 ("일시 중지")으로 진행된 후 표시됩니다. 어떤 키를 누른 후에 나타납니다.

a_vector.~vector_of_int(); 
    b_vector.~vector_of_int(); 
    c_vector.~vector_of_int(); 
    cout << "\n"; 
    system("pause"); 
    return 0; 

주요의 중괄호 종료 후 다시 소멸자를 호출하는 메인 .exe입니다 : 여기) (주의 끝은? 3 개의 소멸자 문 모두에 주석을 달면 오류가 더 이상 표시되지 않습니다.

감사합니다.

+1

관련 코드 및 3의 규칙을 따랐다는 사실 +1. hmjd가 솔루션을 지적했습니다. –

+0

복사 생성자가 올바르게 보입니다. [copy-and-swap] (http://stackoverflow.com/questions/3279543/what-is-the-copy-and-swap-idiom)을 사용하여 대입 연산자를 구현하면 예외가 발생하지 않고 누수가 방지되고 쉽습니다. –

답변

9

explicity가 객체가 범위를 벗어날 때 자동으로 발생합니다 (코드에서 소멸자를 호출하는 데 사용 된 . 표기법에 따라 할당 된 스택이라고 생각합니다). new을 사용하여 힙에 할당 된 경우에도 여전히 소멸자를 명시 적으로 호출하지 않고 delete을 사용합니다.

또한 할당 연산자에서 this->size은 업데이트되지만 an_array은 업데이트되지 않습니다. a_vector.size > this->size 인 경우 delete[]new[]an_array과 같이 요소가 충분하지 않으므로 an_array에 범위를 벗어난 액세스가 발생합니다.

+0

안녕하세요, 그게 제가 생각한 것입니다. 나는 그 문제가 크기가 더 클 수 있다는 것을 깨닫고 이것을 게시 한 후에 고쳤습니다. 감사! – wzaman

1

나는 당신이이 같은 벡터 만든 가정 :

vector_of_int v; 

다음 그것을 삭제하지 마십시오 - 그것은 자동 스토리지입니다. 경우 범위

의 끝에서 자동으로 삭제됩니다 당신은 당신의 벡터를 만들었습니다 그것을 제거

vector_of_int *v = new vector_of_int(); 

전화 delete 운영자 :

delete v; 
2

그것은에서 보이는 소멸자를 명시 적으로 호출하는 코드 그것이 합법적이고 어떤 용도로 사용되는 반면, 소멸자를 명시 적으로 호출하면 안됩니다. 객체가 범위를 벗어 났을 때 자동으로 호출되기 때문에 (또는 delete이 포인터로 호출됩니다.) 이미 파괴 된 객체에 대해 소멸자를 실행하는 것은 정의되지 않은 동작입니다.

특정 코드에서 소멸자는 아마도 메모리를 해제하고 있습니다. 두 번째로 (로컬 변수의 범위에서 자동 호출) 수동 호출로 이미 해제 된 메모리를 해제하려고 시도하고 런타임 에러.

1

할당 연산자에서 항목을 한 배열에서 다른 배열로 복사합니다. 하지만 로컬 배열의 매개 변수가 연산자에 전달되는 매개 변수보다 작 으면 어떨까요? 배열의 크기를 초과합니다.