2010-03-18 63 views
1

這是有效的C++(例如不調用UB),並實現我想要的內容,而不會泄漏內存? valgrinds抱怨freedelete不匹配,但最後說「無泄漏是可能的」。new [n]並刪除每個位置刪除,而不是整個塊刪除[]

int main() { 
    int* a = new int[5]; 
    for(int i = 0; i < 5; ++i) 
    a[i] = i; 

    for(int i = 0; i < 5; ++i) 
    delete &a[i]; 
} 

的原因,我問:我有一個使用boost::intrusive::list和我new被添加到列表中的每個對象的類。有時我知道有多少對象要添加到列表中,並且正在考慮使用new[]來分配一個塊,並且仍然能夠使用boost::intrusive的Disposer樣式自行處理每個對象的delete

回答

8

沒辦法。你不能對未被新分配的內容調用delete,否則你會得到堆損壞。

您會發現,由new []創建的數組沒有分配n個單獨的對象,而是一個數組。數組的第二個對象位於分配塊的中間。

+2

沒錯。而且,當你使用new(或new [])分配某些內容時,它會在某個表的某處存儲一個符號,以便分配特定的內存塊。相應的刪除(或刪除[])調用將查找該表示法。 「 – 2010-03-18 23:32:54

+0

」你不能對新的未分配的內容調用delete,否則你會得到堆損壞。「 你會崩潰! – 2010-03-18 23:59:44

1

您可以添加一點,這樣每個對象都會記住它是否是連續數組中的第一個。這是棘手:

delete object語法
  • 完全不相容
  • 與繼承不相容
  • 處理器而不是調用析構函數明確,如object.~ListItem()
  • 仍然必須使用陣列operator new[]
  • 務必處置反向對象順序,與您的示例不同
  • 析構函數通過其第一個元素實現數組的反射所有權:

ListItem::~ListItem() { 
    if (m_own_my_subarray) { 
     operator delete[](this); // does not invoke any destructor! 
       // "this" must be exactly the result of new[]! 
    } 
} 
+0

當我使用intrusive :: list_base_hooks時,它必須與繼承兼容。 – pmr 2010-03-19 00:09:16

+0

@pmr:'ListItem'當然可以從** **繼承,但是析構函數必須如圖所示。出於同樣的原因和同樣的意義,C風格的對象數組與繼承是不兼容的。 – Potatoswatter 2010-03-19 00:24:33

+0

@pmr:我的意思是ListItem可以*從'list_base_hook'繼承*。你能描述一下我沒有回答你的問題,或者以積極的態度承認嗎?這不是一個簡單的問題來回答,我有一個關於膝蓋下意識「這是不可能的」的迴應... ... – Potatoswatter 2010-03-19 03:49:55