2009-01-12 83 views
7

我有這樣的結構:陣列結構和新/刪除

class Items 
{ 
private: 
    struct item 
    { 
     unsigned int a, b, c; 
    }; 
    item* items[MAX_ITEMS]; 
} 

說我想「刪除」項目,就像這樣:

items[5] = NULL; 

而且我創建了一個新項目對同一地點後:

items[5] = new item; 

我還需要撥打delete[]來打掃一下嗎?或者不會需要這樣做,因爲在編譯之前已知數組items[]的範圍?

將該指針設置爲NULL有效還是應該在那裏調用delete?

回答

15

在將其設置爲NULL之前,您需要先撥打delete。 (將它設置爲NULL不是必需的,如果在刪除指針後不小心嘗試取消引用,它只是有助於減少錯誤。)

請記住,每次使用new時,都需要稍後使用delete指針。不要使用其他的。

此外,new []delete []一起去以同樣的方式,但你不應該用deletenewdelete []混合new []。在您的示例中,由於您使用new(而不是new []將創建對象數組)創建對象,因此必須使用delete(而不是delete [])刪除該對象。

0

C++不是我的強項,但我敢肯定如果將指針設置爲NULL,則會泄漏內存。

編輯:被泄漏的內存將被指向數組中的指針的內存。

0

將項目[5]設置爲NULL不會刪除與該項目關聯的內存,它只是將指向該項目的指針設置爲NULL,因此內存泄漏。

可以通過調用刪除的項目:

delete items[5]; 

由於C++有沒有自動垃圾收集,您需要刪除任何內存不再需要。

6

正如Kluge指出的那樣,您會像索引5那樣泄漏對象。但是,這聽起來像你不應該手動這樣做,但使用Item內的容器類。如果您實際上不需要將這些item對象存儲爲指針,請使用std::vector<item>而不是指向MAX_ITEMS指針的數組。如果需要,您總是可以在中間插入或擦除矢量元素。

如果你需要存儲的對象的指針(通常如果結構item實際上是多態的,不像在你的例子),你可以從Boost.PtrContainer而使用的boost :: ptr_vector <項目>。

實施例:

class Items { 
private: 
    struct item { 
     unsigned int a, b, c; 
    }; 
    std::vector<item> items; 
} 

if (items.size() > 5) // (just to ensure there is an element at that position) 
    items.erase(items.begin() + 5); // no need to use operator delete at all 
1

要刪除的項目使用:

刪除項目[5];

刪除該項目後,建議將刪除的指針設置爲NULL,這樣如果您以後再次將其刪除,您將不會有錯誤。

項[5] = NULL

+0

我接受這個回答 – karthik 2011-02-28 09:02:46

1

說我想 '刪除' 項目,像這樣:

項[5] = NULL;

我知道一點的Visual Basic,但聞起來像一個Visual Basic編程成語,因爲「設置A =無」(或Null,我不知道)將刪除被指向的對象(或而是爲COM對象減少其引用計數)。


正如別人指出的,你應該使用:

delete items[5]; 
items[5] = newContent; 

或:

delete[5]
delete items[5]; 
items[5] = NULL; 

後,纔可能使用存儲在items[5]指針是造成你麻煩。更糟糕的是,它可能會在一開始就工作,並且只有當您在之前由*items[5]使用的空間分配了其他東西時纔會開始失敗。這些是C/C++編程「有趣」的原因,即真正煩人(即使像我這樣喜歡C的人)。

只寫delete items[5];節省了可能是無用的寫入,但這是一個過早的優化。

1

只是要清楚:你指的是調用「delete[]」。我想你的意思是delete

我提到這是因爲C++有兩個獨立的運算符operator deleteoperator delete[]。後者用於刪除使用operator new[]分配的對象數組,而不是適用於這種情況。您有一組指針指向對象,您必須通過重複調用operator new而不是對operator new[]進行單個調用來初始化該對象。

我真的想說的是:你使用delete[]是混淆和模棱兩可的;將其更改爲delete

1

有幾個,相關的,問題在這裏:

  1. 按照陣列本身並不在堆上分配,除非struct是你發佈的代碼,所以你不需要delete[]的陣列。如果您使用new[]創建陣列,則必須使用delete[]
  2. 發佈的代碼沒有說明如何分配從數組指向的對象。如果你在堆棧中分配這些對象,那麼你不應該刪除它們(然後再次,這是非常不可能的,因爲當它們指向的對象超出範圍時,你的指針將變爲無效)。如果您將它們分配在堆上(使用新的),那麼當必須在超出範圍時將其刪除。
  3. 正如其他人已經建議的那樣,如果使用容器(尤其是STL容器)和智能指針(現在指的是指向Boost的指針),生活會更容易。