我有代码:

std::list<Node *> lst;
//....
Node * node = /* get from somewhere pointer on my node */;
lst.remove(node);
std::list::remove方法是否调用每个删除的元素的析构函数(和可用内存)?如果是这样,我该如何避免呢?

最佳答案

是的,从容器中删除Foo*会破坏Foo*,但不会释放Foo。销毁原始指针始终是无操作的。别无选择!让我给你几个原因。

储物类

仅当指针实际上是动态分配的时,才删除指针才有意义,但是运行时如何才能知道销毁指针变量时是否是这种情况?指针也可以指向静态和自动变量,并删除其中之一会产生undefined behavior

{
    Foo x;
    Foo* p = &x;

    Foo* q = new Foo;

    // Has *q been allocated dynamically?
    // (The answer is YES, but the runtime doesn't know that.)

    // Has *p been allocated dynamically?
    // (The answer is NO, but the runtime doesn't know that.)
}

悬空指针

无法确定过去是否已经释放过该指针。两次删除同一指针将产生undefined behavior。 (在第一次删除后,它变成了悬空的指针。)
{
    Foo* p = new Foo;

    Foo* q = p;

    // Has *q already been released?
    // (The answer is NO, but the runtime doesn't know that.)

    // (...suppose that pointees WOULD be automatically released...)

    // Has *p already been released?
    // (The answer WOULD now be YES, but the runtime doesn't know that.)
}

未初始化的指针

也根本无法检测到指针变量是否已初始化。猜猜当您尝试删除此类指针时会发生什么?再次,答案是undefined behavior
    {
        Foo* p;

        // Has p been properly initialized?
        // (The answer is NO, but the runtime doesn't know that.)
    }

动态数组

类型系统不区分指向单个对象的指针(Foo*)和指向对象数组的第一个元素的指针(Foo*)。销毁指针变量后,运行时可能无法确定是通过delete还是通过delete[]释放指针。通过错误的格式发布会调用undefined behavior
{
    Foo* p = new Foo;

    Foo* q = new Foo[100];

    // What should I do, delete q or delete[] q?
    // (The answer is delete[] q, but the runtime doesn't know that.)

    // What should I do, delete p or delete[] p?
    // (The answer is delete p, but the runtime doesn't know that.)
}

概要

由于运行时无法对指针进行任何有意义的操作,因此销毁指针变量始终是无操作的。由于不知情的猜测,什么也不做绝对比导致未定义的行为好:-)

忠告

考虑将智能指针用作容器的值类型,而不是原始指针,因为它们负责在不再需要时释放指针。根据您的需要,使用std::shared_ptr<Foo>std::unique_ptr<Foo>。如果您的编译器尚不支持C++ 0x,请使用boost::shared_ptr<Foo>

Never,我重复一遍,从来没有使用std::auto_ptr<Foo>作为容器的值类型。

关于c++ - std::list::remove方法是否调用每个已删除元素的析构函数?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/4260464/

10-12 16:39
查看更多