2017-04-19 5 views
0

멤버로 다른 개체에 대한 포인터가있는 형식이 있습니다. 객체 (Demo)가 생성되면 생성자에서 다른 객체 (Property)를 초기화합니다. 이 객체가 많은 경우 다른 것으로 속성을 변경할 때 힙 공간을 낭비하고 싶지 않으므로 setProperty에 초기화 된 메모리를 해제 한 다음 데모의 디 컴포지션에서 다시 삭제합니다. 그 시점까지는 다른 무언가로 설정되었습니다. 그러나 이로 인해 코드가 충돌합니다. property을 재설정 할 때 재 할당하는 이유는 무엇입니까?C++ 포인터가되는 기본 개체 멤버를 삭제하는 방법

class Property{ }; 


class Demo{ 
    protected: 
      Property *property; 
    public: 
      Demo(){ property = new Property();}; 

      void setProperty(Property *p){ 
        delete property; 
        property = p; 
      }; 

      ~Demo(){ 
        delete property; 
      }; 
}; 

int main(){ 
    Property p = Property(); 
    Demo * d = new Demo(); 

    d->setProperty(&p); 

    delete d; 
} 
+1

'속성'은 어디에 선언 되었습니까? 또한'delete' 만 사용하여'new'로 생성 된 것을 해제합니다. 'main()'의'p'는 스택에 할당되어 있으므로'Demo :: ~ Demo()'는 스택 할당 객체를 효과적으로 삭제하고 있습니다. 이것은 정의되지 않은 동작입니다. – cdhowie

+0

이것도 컴파일되지 않는다는 것 외에도 ('속성'은 존재하지 않습니다), 여기서 많은 오해가 있습니다. 어디서부터 시작해야할지조차 모릅니다. 왜 동적 할당을 사용하여 처음부터기도하고 있습니까? –

+0

당신은 [규칙 3] (https://en.wikipedia.org/wiki/Rule_of_three_ (C % 2B % 2B_programming))을 위반하고 있으며, 당신은' 새로운 '. –

답변

5

당신은하지 new에 의해 생성 된 객체의 주소를 통과 한 후 delete에보십시오. 이것은 정의되지 않은 동작입니다.

가장 가능성이 높은 충돌 과정은 표준 라이브러리도 Property p을 해제한다는 것입니다. 프로그램을 끝내면 다시 p이 해제됩니다.

가능한 "수정"은 삭제할 수있는 객체 (예 : new)를 전달하는 것입니다.

int main(){ 
    Property *p = new Property(); 
    Demo * d = new Demo(); 

    d->setProperty(p); // Demo is responsible for freeing `p`. 

    delete d; 
} // standard libraries do clean up objects from `main` here 

수행하려는 작업을보다 효과적으로 수행 할 수 있습니다. 이 대답은 충돌을 설명합니다.

당신은 무료인지 아닌지를 결정하는이 desing에서 꽤 어렵습니다. 따라서 코드는 매개 변수의 출처에 따라 다릅니다. 그것은 디자인을위한 붉은 깃발이어야합니다.

3

표준 라이브러리에서 제공하는 적절한 도구를 사용하여 모든 메모리 관리 문제를 제거하십시오.

#include <memory> 

class Property{ }; 


class Demo{ 
    protected: 
      std::unique_ptr<Property> property; 
    public: 
      Demo() 
      : property { new Property() } 
      { } 

      void setProperty(std::unique_ptr<Property> p){ 
       property = std::move(p); 
      }; 

    // un-necessary 
    //  ~Demo(){ 
    //    delete property; 
    //  }; 
}; 

int main(){ 
    auto p = std::unique_ptr<Property>(new Property); // or in c++14: = std::make_unique<Property>(); 
    auto d = std::unique_ptr<Demo>(new Demo); // or in c++14: = std::make_unique<Demo>(); 

    d->setProperty(std::move(p)); 

    // no longer necessary 
    // delete d; 
}