开发者

Is it possible to delete a non-new object?

开发者 https://www.devze.com 2023-01-28 04:14 出处:网络
I have an object with a vector of pointers to other objects in it, something like this: class Object {

I have an object with a vector of pointers to other objects in it, something like this:

class Object {
    ...
    vector<Object*> objlist;
    ...
};

Now, Objects will be added to list in both of these ways:

Object obj;
obj.objlist.push_back(new Object);

and

Object name;
Object* anon = &name;
obj.objlist.push_back(anon);

If a make a destructor that is simply

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

Will there be any adverse consequences in terms of when i开发者_Python百科t tries to delete an object that was not created with new?


Yes, there will be adverse effects.

You must not delete an object that was not allocated with new. If the object was allocated on the stack, your compiler has already generated a call to its destructor at the end of its scope. This means you will call the destructor twice, with potentially very bad effects.

Besides calling the destructor twice, you will also attempt to deallocate a memory block that was never allocated. The new operator presumably puts the objects on the heap; delete expects to find the object in the same region the new operator puts them. However, your object that was not allocated with new lives on the stack. This will very probably crash your program (if it does not already crash after calling the destructor a second time).

You'll also get in deep trouble if your Object on the heap lives longer than your Object on the stack: you'll get a dangling reference to somewhere on the stack, and you'll get incorrect results/crash the next time you access it.

The general rule I see is that stuff that live on the stack can reference stuff that lives on the heap, but stuff on the heap should not reference stuff on the stack because of the very high chances that they'll outlive stack objects. And pointers to both should not be mixed together.


No, you can only delete what you newed

Object* anon = &name;

When name goes out of scope, you will have an invalid pointer in your vector.


What you're actually asking is whether it's safe to delete an object not allocated via new through the delete operator, and if so, why?

Unfortunately, this is obfuscated by some other problems in your code. As mentioned, when name goes out of scope, you're going to end up with an invalid pointer.

See zneak's answer for why your original question doesn't result in a safe operation, and why the scope for name actually matters.


This will not work - if you delete an object that wasn't allocated by new you've violated the rules or the delete operator.

If you need to have your vector store objects that may or may not need to be deleted, you'll need to keep track of that somehow. One option is to use a smart pointer that keeps track of whether the pointed to object is dynamic or not. For example, shared_ptr<> allows you to specify a deallocator object when constructing the shard_ptr<> and as the docs mention:

For example, a "no-op" deallocator is useful when returning a shared_ptr to a statically allocated object

However, you should still be careful when passing pointers to automatic variables - if the vector's lifetime is longer than the lifetime of the variable then it'll be refering to garbage at some point.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号