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?

4

8 回答 8

16

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

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

此外,new []delete []以相同的方式一起使用,但你不应该new []deletenew混合delete []。在您的示例中,由于您使用new(而不是new []创建对象数组)创建了对象,因此您必须使用delete(而不是delete [])删除对象。

于 2009-01-12T01:04:56.117 回答
6

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

如果您需要将对象存储为指针(通常如果 structitem实际上是多态的,与您的示例不同),您可以使用Boost.PtrContainer中的 boost::ptr_vector<item>代替。

例子:

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
于 2009-01-12T01:13:30.453 回答
1

要删除项目,请使用:

删除项目[5];

删除项目后,最好将删除的指针设置为 NULL,这样以后再误删除就不会报错了。

项目[5] = NULL

于 2009-01-12T01:14:34.960 回答
1

假设我想“删除”一个项目,如下所示:

项目[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];节省了可能是无用的写入,但这是一个过早的优化。

于 2009-01-12T01:50:00.473 回答
1

为了清楚起见:您指的是调用“ delete[]”。我想你的意思是delete

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

我真正想说的是:您的使用delete[]令人困惑和模棱两可;将其更改为delete.

于 2009-01-12T08:07:43.160 回答
1

这里有一些相关的问题:

  1. 根据您发布的代码,除非struct是,否则数组本身不会在堆上分配,因此您不需要delete[]数组。如果你用你创建了数组,new[]你将不得不这样delete[]做。
  2. 发布的代码没有说明如何分配从数组中指向的对象。如果您在堆栈上分配这些对象,则不能删除它们(同样,这是极不可能的,因为当它们指向的对象超出范围时,您的指针将变得无效)。如果您在堆上分配它们(使用新的),那么当它们超出范围时您必须删除它们。
  3. As others have already suggested, life is much easier if you use a container -- especially an STL container -- and smart pointers -- which for now means pointers out of Boost.
于 2009-01-12T08:20:57.050 回答
0

C++ 不是我的强项,但我很确定如果你将指针设置为NULL.

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

于 2009-01-12T00:57:08.880 回答
0

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

您可以通过调用删除该项目:

delete items[5];

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

于 2009-01-12T00:59:57.563 回答