2012-05-11 2 views
1

현재 프로젝트에 어려움을 겪고 있습니다. 이전 버전에서는 std :: vectors를 사용했는데 메모리 누수가없고 에러도 없었습니다.C++ 소멸자 - 삭제 시점과 사용 시점

그런 다음 좀 더 우아하고 성능이 약간 향상되었으므로 포인터를 사용하도록 전환했습니다.

그래서 나는

class A 
{ 
    private: 
     std::string str; 
    public: 
     A() {str = "";} 
}; 

class B 
{ 
    private: 
     std::string str; 
     A* a; 
    public: 
     B() {str = ""; a = NULL; } 
}; 

class C 
{ 
    private: 
     std::vector<B*> bs; 
    public: 
     C() { bs = std::vector<B*>(); } 

}; 

내가 new을 사용할 때마다, 나는 나중에 delete을한다는 것을 알고 같은 클래스가 있습니다. 그래서 class Bclass C에 대한 소멸자를 만듭니다. 나는 그것을 같이해야한다고 생각 무엇

:

B::~B() 
{ 
    if (this->a != NULL) 
     delete this->a; 
} 

C::~C() 
{ 
    while ((this->bs).size() > 0) 
    { 
     if ((this->bs).back() != NULL) 
      delete (this->bs).back(); 
     (this->bs).pop_back(); 
    } 
    (this->bs).clear(); // not necessary since bs has size 0? 
} 

하지만 그와

, 나는 그런 Valgrind의에서 "크기 4의 잘못된 읽기"등의 다양한 오류를 받고 있어요.

소멸자가 어떻게 보이는지에 대한 제 아이디어는 무엇입니까? 내 코드에서 다른 문제가있을 수 있습니까? 개인 std::string 회원을 std::string -pointers (으)로 변경하는 것이 좋습니까? 소멸자에서 str = "";을 수행하는 것이 필요하거나 좋은 일인가?

사이드 노트 : "적절한 소멸자"와 비슷한 키워드에 대해 많은 검색을 했으므로 도움이되지 않았습니다. 당신은 이것이 너무 자주 요청되었다고 생각한다면 : 나는 그것을 얻지 못하기 때문에 나는하지 않습니다. 롭 말했다 무엇

+5

아, 하, 하, 하 - 나는 우아함에 대한 당신의 생각은 약간 결함이 생각! 효율성에 관해서 ... 당신은이 증가를 증명하기 위해 성능 테스트를 했습니까 ?? – Nick

+3

"std :: vectors를 사용했으며 모두 괜찮 았습니다." 예, 일반적으로'std :: vector'의 경우입니다. 그게 당신에게 무엇을 말합니까? –

+0

특별한 테스트가 필요 없습니다 ;-) 성능이 약 3 배 빨라졌습니다. – stefan

답변

1

, 또한 당신의 소멸자가 단순화 될 수있다 :

B::~B() 
{ 
    delete a; 
} 

C::~C() 
{ 
    for (size_t i = 0; i < bs.size(); ++i) 
     delete bs[i]; 
} 
+0

! = NULL을 확인해야하는 이유는 무엇입니까? 나는 NULL 포인터를 삭제하는 것이 불법이라고 생각했다. – stefan

+1

null 포인터를 삭제하는 것은 완벽합니다. –

+0

C++ 2003 표준 §5.3.5/2를 인용하면 "delete 피연산자의 값이 null 포인터 인 경우 은 아무 효과가 없습니다." –