2014-01-30 4 views
0

나는 내가 작업이 코드를 작성 A.'새로운'인스턴스를 생성하면 소멸자 충돌을 해결할 수 있습니까?

전화 할게 클래스의 하위 클래스, B를 생성, 그래서 나는 실제 코드 일반화거야 :

class A 
{ 
public: 
    A() 
    { 
    important_variable = new Type(); 
    ... 
    }; 

    ~A (void) { delete(important_variable); };  // Default destructor 
    // more methods 

protected: 
    Type  *important_variable; 
}; 

class B : public A 
{ 
public: 
B() : A() { important_variable = another_var; } 
~B() {}; 

Type *another_var; 
}; 

을 B에 대한이 코드를 사용하면 프로그램이 '처리되지 않은 예외'로 인해 충돌을 일으켰습니다. 이제

, 나는 여기에 클래스 B의 코드를 변경할 때 :

class B : public A 
{ 
public: 
B() : A() { another_var = new Type(); important_variable = another_var; } 
~B() {}; 

Type *another_var; 
}; 

예외는 사라집니다.

A가 다른 변수가 가리키는 변수를 삭제하려고했기 때문에 B에 대한 원래 코드로 인해 프로그램이 중단되는 것으로 생각합니다. 이 논리가 맞습니까? B에 대한 새 코드가 내 프로그램을 작동시키는 이유는 무엇입니까?

+0

추측이 맞을 수도 있습니다 (더 많은 코드를 보지 않고는 말할 수 없습니다). 두 번째 코드는 각 인스턴스에 대해 새 객체를 만들기 때문에 작동하므로 삭제할 때마다 다른 인스턴스의 발가락을 밟지 않습니다. 하지만 코드에 메모리 누수가 있습니다. 포인터를 사용했던 객체에 대해 무언가를하지 않고 포인터를 재 할당 할 수는 없습니다. – Dave

답변

2
코드에서 많은 결함이있다

하지만 충돌이 발생할 가능성이 가장 높은 사람은이 라인이다. 그러나 important_variable은 같은 위치를 가리 키도록 지정되고 A의 생성자에서 삭제됩니다.

"해결책"은 메모리 누수를 희생시키면서 문제를가립니다. 이

another_var = new Type(); important_variable = another_var; 

을 수행 할 때 important_variable가 지적하는 원래 동적으로 할당 Type 개체가 손실됩니다합니다.

그 외에도 rule of three을 따라야합니다.

+0

첫 번째 코드에는 메모리 누수가 있습니다. – Dave

+0

기존 기능을 유지하면서 메모리 누수를 제거하려면 어떻게해야합니까? – Undefined

+0

@Dave 예, 가능합니다. – juanchopanza

0

새로운 및 삭제는 힙 할당을 처리하기위한 것입니다. B 클래스의 첫 번째 목록에서 another_var이 스택에 할당되어있는 것으로 의심되는데 이는 소멸자에서 예외를 발생시키는 원인입니다. 또한 기본 클래스가있을 때마다 반드시 소멸자를 만들어야합니다 virtual.

important_variable = another_var; 

another_var

가 삭제 될 수 있습니다 어디를 가리 키지 않습니다

0

important_variable을 초기화되지 않은 another_var으로 설정하고이 초기화되지 않은 값을 삭제하려고했기 때문에 원본 버전이 손상되었습니다. "수정 된"버전에서는 적어도 초기화되지 않은 변수는 삭제하지 않고 여전히 메모리 누수가 있습니다. 새로 할당 된 메모리를 important_variable에 할당 한 다음 즉시이 변수에 another_var의 값을 할당하면 원래 할당 된 메모리는 no입니다. 더 이상 접근 할 수 없으며 누설됩니다.

관련 문제