2010-04-05 2 views
1

두 개의 클래스가 work 및 workItem을 만들었습니다.클래스 목록에서 메모리를 확보하는 방법

 CWorker *work = new CWorker(); 
     CWorkItem *workItem = new CWorkItem(); 

작업 클래스에는 공개 목록 m_WorkList가 있으며 여기에 작업 항목이 추가됩니다.

work->m_WorkList.push_back(workItem); 

난 그냥

if(work != NULL) 
delete work; 

나는 다음과 같은 소멸자의 목록을 반복해야합니까 작업을 삭제하면? 이 작업을 수행하는 더 좋은 방법은 무엇입니까? 대신 명확하게 사용할 수 있습니까?

while(m_WorkList.size()) 
{ 
    CWorkItem *workItem = m_WorkList.front(); 
    m_WorkList.pop_front(); 
    if(workItem) 
     delete workItem; 
} 
+0

삭제하기 전에 null을 확인할 이유가 없습니다. null을 삭제하는 것은 아무 작업이 아닙니다. 또한 동적으로 할당 할 필요가 있습니까? 이상적으로 당신은 그걸로 끝내지 않을 것입니다. – GManNickG

답변

4

예, 각 항목은 delete입니다. new 번 N 번 전화를 걸면 delete 번을 정확히 N 번 호출해야합니다. 대량 삭제 항목에는 바로 가기가 없습니다.

또한 완료하면 delete (work)으로 전화해야합니다.

힙에 항목 배열을 만들고 힙에 항목을 한 번에 릴리스하려면 new[]delete[]을 사용할 수 있습니다. 그러나 당신의 경우에 이것은 당신이 찾고있는 것이 아닙니다.

이러한 삭제 호출을 수동으로 수행하지 않으려면 boost::shared_ptr을 사용할 수 있습니다.

2

다른 곳에서 workItem 목록을 유지 관리하지 않는다고 가정하면 Worker 자체를 삭제하기 전에 참조를 잃기 전에 개별적으로 삭제해야합니다. 작업자가 유일한 목록을 보유하고 있다면 해체자는 다른 작업자와 마찬가지로 적절한 위치에 있습니다. 그렇지 않으면 작업자 자체에서 삭제를 호출하기 전에 각 작업 항목을 "수동으로"삭제해야합니다.

그러나 workItems 참조 다른 위치에 있으면 작업자를 삭제할 때 적절한 시간을 선택하여 삭제할 수 있습니다.

3

다른 응답에서 말한 것처럼 목록을 반복하고 각 요소를 삭제해야합니다. 명확하게 호출하면 포인터가 아닌 포인터가 목록에서 제거됩니다.

소유권 개념이있는 목록이 필요하면 boost pointer container을 사용할 수 있습니다. 귀하의 목록을 파괴하면 개체가 파괴된다는 것을 보장합니다.

1

정말 소유권에 따라 달라 지므로 인터페이스를 작성할 때 결정해야합니다. 방법이 있다고 가정 해보십시오.

메모리를 소유 한 사람을 지정해야합니다. 따라서 누가 그것을 삭제해야합니까? 수행하려는 작업에 따라 호출자가 항목을 소유하고 (항목이 CWorkers간에 일상적으로 공유되어야하는 것처럼) 또는 CWorker가 소유하도록해야합니다 (각 CWorkItem이 단일 CWorker에 속하는 경우). 그것을 소유 한 사람은 그것을 삭제해야 할 책임이 있습니다.

이전의 경우 WorkItems를 shared_ptrs로 사용하여 Workers간에 공유되는 소유권을 지정하면 수동으로 삭제하지 않아도됩니다. 후자의 경우 ptr_vector과 같은 특수 컨테이너를 사용하여 수동 삭제의 필요성을 없앨 수 있지만 메모리를 제어하는 ​​기능에 대한 메모 만 사용해야합니다.이는 곧 것이다 (pop_front()

1

사용 부스트 shared_ptr을보다) (당신이 if 문 사람들을 필요로하지 않으며, 그와 pop_back하는 빠른 것, 그래서 또한

, 메모로, 삭제는, 널 안전

typedef boost::shared_ptr<WorkItem> WorkItemPtr; 
    .... 
    std::list<WorkItemPtr> list; 
    ... 
    list.push_back(new WorkItem); 

이제 목록이 삭제되면 WorkItems가 삭제됩니다. 코드에서 WorkItemPtrs를 전달할 수 있으므로 걱정할 필요가 없습니다.

2

다른 사람들이 말했듯이 delete (모든 new)이 필요합니다. 컨테이너는 기본적으로이 작업을 수행하지 않습니다. 목록에서 항목을 팝하지 않아도됩니다. 작업자를 위해 펑터를 만들 수 있습니다. 다음은 tr1::shared_ptr 또는 부스트를 사용할 수없는 사람들을위한 일반적인 방법입니다.

struct deleter 
{ 
    template <class T> 
    void operator()(const T* ptr) const 
    { 
     delete ptr; 
    } 
}; 

// Usage 
std::for_each(work->m_WorkList.begin(), work->m_WorkList.end(), deleter()); 
delete work; 
관련 문제