2013-04-08 2 views
0

저는 C++, 13 장 : 동적 객체 생성에 대해 생각하고 있습니다. 이 장에서 void * 삭제에 대한 Eckel의 말은 아마도 버그 일 수 있습니다. 다음 단락은 나를 혼란스럽게합니다.void * 포인터를 C++에서 삭제

다른 메모리 누수 문제는 컨테이너에있는 각 객체 포인터에 대해 실제로 삭제가 이라는 것을 확인하는 것과 관련이 있습니다. 컨테이너는 void *로 보유하고 있기 때문에 포인터를 "소유"할 수 없으므로 은 적절한 정리를 수행 할 수 없습니다. 개체를 정리하려면 사용자가 의 책임을 져야합니다. 이것은 스택에 작성된 오브젝트에 포인터를 추가하고 에 작성된 오브젝트가 힙에 할당되지 않은 포인터에 대해 안전하지 않기 때문에 동일한 컨테이너에 대한 힙을 작성하면 심각한 문제가 발생합니다.

"스택에 만들어진 개체에 포인터를 추가하고 동일한 컨테이너에 힙에 만들어진 개체"가 심각한 문제를 일으키는 이유에 대해 더 자세히 설명 할 수 있습니까?

문제를보다 명확하게 만들기 위해 관련 코드 스 니펫을 추가합니다.

class Stack { 
    struct Link { 
    void* data; 
    Link* next; 
    void initialize(void* dat, Link* nxt); 
    }* head; 
public: 
    void initialize(); 
    void push(void* dat); 
    void* peek(); 
    void* pop(); 
    void cleanup(); 
}; 
+2

나는 당신이 의미를 잘못 이해했다고 생각합니다. 중요한 것은'void *'를 평범하지 않은 객체 **에 삭제할 수 없다는 것과 ** 스택을 가리킬 수있는 포인터를 삭제할 수 없다는 것을 별도로 명시하고 있습니다. –

+0

가능한 복제본 [void 포인터를 삭제해도 안전합니까?] (http://stackoverflow.com/questions/941832/is-it-safe-to-delete-a-void-pointer) – bobobobo

답변

2

일반적으로 스택의 객체는 삭제 될 필요가 없으므로 힙의 객체가 필요합니다. 동일한 컨테이너에 배치하면 어떻게 삭제할 것인가를 어떻게 추적합니까? 스택에있는 객체 (삭제할 필요가없는 객체)와 힙 (삭제해야 할 객체)의 객체에 대한 컨테이너 등 두 개의 컨테이너가 있어야합니다.

+2

또는 더 나은 방법은, 컨테이너가 할당을 처리하므로 수동으로 삭제를 호출 할 필요가 없습니다. RAII. –

0

이 단락은 실제로 다소 모호합니다. 그것은 두 가지 이슈를 섞어서 혼동을 일으킨다 고 생각합니다.

  1. 개체를 올바르게 삭제하려면 해당 개체의 형식을 컴파일러에 알려야합니다. void*의 경우 유형을 알 수 없습니다 (실제 유형을 숨기기 위해 정확히 void*을 사용하는 지점 임). 따라서 올바른 실제 유형으로 변환하지 않고 삭제를 수행 할 수 없습니다.
  2. 보통 일반적으로 사용되는 void*은 지정된 개체의 소유권이이라는 디자인으로 일부 외부 엔터티 에 속하고 포인터가 포함 된 엔터티가 아니라는 것을 의미합니다. 엔티티 내부에서 포인터는 불투명하며 엔티티와 관련하여 블랙 박스 인 외부 객체에 대한 핸들러 역할을합니다. Stack 클래스는 책임 부서를 잘 알고 있어야하며 void* 개체를 파괴하려고 시도하면 안됩니다 (예 : 스택 변수를 해제하려는 시도로 이어짐) 또는 수행해야 할 작업에 대해 전혀 알지 못하므로 개체를 파괴하려고 시도해서는 안됩니다 파괴시 (기능적 결함으로 이어진다).
관련 문제