结构数组和新/删除

时间:2009-01-12 00:53:36

标签: c++ arrays memory-management struct new-operator

我有这样的结构:

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?

8 个答案:

答案 0 :(得分:15)

在将delete设置为NULL之前,需要调用它。 (将其设置为NULL不是必需的,如果您在删除指针后意外尝试取消引用它,它只会有助于减少错误。)

请记住,每次使用new时,您都需要稍后在同一指针上使用delete。不要在没有另一个的情况下使用它。

此外,new []delete []以同样的方式组合在一起,但绝不应将new []deletenew混合在一起{{1} }。在您的示例中,由于您使用delete []创建了对象(而不是new,这将创建一个对象数组),您必须使用new [](而不是delete删除对象)。

答案 1 :(得分:6)

正如Kluge指出的那样,你会像那样在索引5处泄漏对象。但是这个听起来好像不应该手动执行,而是在Item内使用容器类。如果您实际上不需要将这些item对象存储为指针,请使用std::vector<item>而不是MAX_ITEMS指针数组。如果需要,您也可以随时在中间插入或删除矢量元素。

如果您需要将对象存储为指针(通常,如果struct item实际上是多态的,与示例中不同),您可以使用boost :: ptr_vector&lt; item&gt;取而代之的是Boost.PtrContainer

示例:

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

答案 2 :(得分:1)

要删除项目,请使用:

删除项目[5];

删除项目后,建议将删除的指针设置为NULL,这样如果以后再错误地删除它,就不会出错。

items [5] = NULL

答案 3 :(得分:1)

  

说我想'删除'一个项目,如下:

     
    

items [5] = NULL;

  

我知道Visual Basic很少,但闻起来像是一个Visual Basic编程习惯用法,因为“Set a = None”(或Null,我不确定)会删除a指向的对象(或者更确切地说减少它的引用计数) ,对于COM对象)。


正如其他人所说,你应该使用:

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

或:

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

delete[5]之后,唯一可能使用存储在items[5]中的指针会给您带来麻烦。更糟糕的是,它可能恰好在开始时起作用,并且只有在*items[5]之前使用的空间上分配其他内容时才开始失败。这些是导致C / C ++编程“有趣”的原因,即真的很烦人(即使是像我这样喜欢C的人)。

只写delete items[5];可以保存无用的写入,但这是一种不成熟的优化。

答案 4 :(得分:1)

为了清楚起见:你指的是打电话给“delete[]”。我想你的意思是delete

我之所以提到这一点,是因为C ++有两个独立的运算符,operator deleteoperator delete[]。后者用于删除分配有operator new[]的对象数组,在这种情况下适用。你有一个指向对象的指针数组,你必须通过重复调用operator new来初始化它,而不是一次调用operator new[]

我真正想说的是:你对delete[]的使用令人困惑和含糊不清;将其更改为delete

答案 5 :(得分:1)

这里有一些相关的问题:

  1. 根据您发布的代码,除非struct,否则数组本身不会在堆上分配,因此您不需要delete[]数组。如果您使用new[]创建了数组,则必须delete[]
  2. 发布的代码没有说明如何分配从数组中指向的对象。如果在堆栈上分配这些对象,则不得删除它们(然后再次,这是非常不可能的,因为当指针指向的对象超出范围时,指针将变为无效)。如果您在堆上分配它们(使用new),那么当超出范围时,必须删除它们。
  3. 正如其他人已经建议的那样,如果使用容器(尤其是STL容器)和智能指针,生活会更容易 - 现在这意味着指出了Boost。

答案 6 :(得分:0)

C ++不是我的强项,但如果你将指针设置为NULL,我很确定你会泄漏内存。

编辑:泄漏的内存将是数组中指针指向的内存。

答案 7 :(得分:0)

将items [5]设置为NULL不会删除与该项关联的内存,它只是将指向该项的指针设置为NULL,因此内存被泄露。

您可以通过以下方式删除该项目:

delete items[5];

由于C ++没有自动垃圾收集,您需要删除不再需要的任何内存。