是否可以删除非新对象?

16 c++ destructor memory-management new-operator

我有一个对象,其中包含指向其他对象的指针向量,如下所示:

class Object {
    ...
    vector<Object*> objlist;
    ...
};
Run Code Online (Sandbox Code Playgroud)

现在,对象将以这两种方式添加到列表中:

Object obj;
obj.objlist.push_back(new Object);
Run Code Online (Sandbox Code Playgroud)

Object name;
Object* anon = &name;
obj.objlist.push_back(anon);
Run Code Online (Sandbox Code Playgroud)

如果做一个简单的析构函数

~Object {
    for (int i = 0; i < objlist.size(); i++) {
        delete objlist[i];
        objlist[i] = NULL;
    }
}
Run Code Online (Sandbox Code Playgroud)

在尝试删除未使用new创建的对象时会不会产生任何不良后果?

zne*_*eak 37

是的,会有不利影响.

您不能delete是未分配的对象new.如果对象是在堆栈上分配的,则编译器已在其作用域的末尾生成对其析构函数的调用.这意味着您将两次调用析构函数,可能会产生非常糟糕的影响.

除了两次调用析构函数之外,您还将尝试释放一个从未分配过的内存块.该new操作可能使堆上的对象; delete期望在new运营商放置它们的同一区域中找到该对象.但是,您的对象未new在堆栈上分配生命.这很可能会导致程序崩溃(如果第二次调用析构函数后它还没有崩溃).

如果你Object在堆上的时间长于你Object在堆栈上的时间,那么你也会陷入深深的麻烦:你会在堆栈的某个地方得到一个悬空引用,下次访问它时你会得到不正确的结果/崩溃.

我看到的一般规则是,堆栈上的东西可以引用堆上的东西,但是堆上的东西不应该引用堆栈上的东西,因为它们很可能会比堆栈对象更长.两者的指针不应该混在一起.


Dar*_*con 5

不,你只能吃delete什么new

Object* anon = &name;
Run Code Online (Sandbox Code Playgroud)

当名称超出范围时,向量中将具有无效的指针。