2010-04-05 36 views
1

說我有兩個類創建工作和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 2010-04-05 17:05:34

回答

4

是的,你需要delete每個項目。如果您撥打new N次,則您需要撥打delete N次。批量刪除項目沒有快捷方式。

另外,當你完成它,你需要撥打電話deletework

如果您想要在堆上創建一個項目數組並在一次釋放堆中的項目,則可以使用new[]delete[]。但在你的情況下,這不是你想要的。

如果您不想手動執行這些刪除調用,則可以查看boost::shared_ptr

2

假設您沒有在其他地方維護一個workItems列表,那麼是的,您需要單獨刪除它們中的每一個,然後刪除Worker本身(因此失去參考)。如果工作者擁有唯一的名單,那麼解構者就像任何一個地方一樣好(否則,在你呼叫工人本身的刪除之前,你需要手動刪除每個工作項目)

但是,如果workItems參考在其他地方存在,您可以選擇適當的時間刪除它們,刪除Worker時可能會也可能不會。

3

如在其他回覆中所述,您需要遍歷列表並刪除每個元素。如果你調用清除,它只會從列表中刪除指針而不是指向對象。

如果您需要一個包含所有權概念的列表,您可以使用boost pointer container。它會確保你的物品在銷燬你的清單時被破壞

1

它確實取決於所有權,這是您在構建界面時需要決定的。假設你有一個方法:

CWorker::AddItem(CWorkItem *workItem) 

你需要指定誰擁有的內存,併爲此誰應該刪除。根據你正在嘗試做的事情,調用者擁有它是有意義的(例如,如果項目應該在CWorkers之間定期共享),或者讓CWorker擁有它(如果每個CWorkItem屬於單個CWorker)。擁有它的人有責任刪除它。

在前一種情況下,您可以將WorkItems設置爲shared_ptrs,以指定所有者在工人之間共享,並且您不需要手動刪除。在後一種情況下,您也可以使用像ptr_vector這樣的專用容器來避免手動刪除的需要,但是您還應該記錄關於正在控制內存的功能。

此外,作爲一個說明,刪除是空安全的,所以你不需要這些if語句,這將是更快pop_back()比pop_front()

1

使用升壓shared_ptr的(它會很快成爲標準)

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

現在,當刪除列表時,WorkItems將被刪除。您可以在代碼中傳遞WorkItemPtrs,而不必擔心它們。

2

正如其他人所說,你需要一個delete與每new。容器默認不會爲你做這個。儘管如此,您不需要將項目從列表中彈出。您可以創建一個函數來爲您完成工作。以下是不能使用tr1::shared_ptr或Boost的人的常見做法。

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;