2009-01-12 51 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的指针),生活会更容易。