tags:

views:

144

answers:

6

Is it bad/illegal C++ to delete manually objects from a stack or there are situation when it is acceptable?

Edit

Constructor(pointer parent, pointer left, pointer right):parent_(parent),left_(left), right_(right)
{   }

   ~Constructor()
        {
        delete parent_;
        delete left_;
        delete right_;
        }


main()
{
Object parent;
Object left;
Object right;
Constructor c(&parent,&left,&right);
}

Is there any way to check if object is on heap or on stack?

+12  A: 

You are only allowed to delete those objects that have been allocated with new. If you try to call delete on a pointer pointing to an object on the stack, you will probably crash your program.

sth
A: 

Usually you will have a method which allows you to edit the stack and usually the actual stack isn't exposed to the outside world to be manipulated outside the accessors defined on the class. So I'd say it is bad because there could be other properties and state inside the object representing the stack that become unsynced when you remove items manually.

Achilles
+4  A: 

Yes, it is bad to delete automatic variables (ie, objects on the stack). I suppose there is still no "never" in programming, but I can't think of a time/reason why you would want to do this.

What scenario are you thinking of?

EDIT: Actually, not only is it bad, it is illegal:

5.3.5 Delete

1: The delete-expression operator destroys a most derived object (1.8) or array created by a new-expression.

John Dibling
@Roger no I mean stack as opposite to heap.
There is nothing we can do
I can bet you can say 'no never' in this particular case...
David Rodríguez - dribeas
@John Dibling Thanks that is what I wanted to know. Illegal. Great.
There is nothing we can do
@There: You updated the question with code so I deleted the comment (before I saw your reply); you may want to change "a stack" (for everyone else: I thought this could mean something like std::stack, and deleting objects owned by containers is bad) to "the stack".
Roger Pate
What about deleting an object created by placement new? This should be illegal/undefined, right? Or is the terminology such that placement new doesn't create an object?
Philipp
@Philipp: Do not `delete` object created with placement `new`. You should only `delete` the original buffer. There is no "placement delete". See here: http://www2.research.att.com/~bs/bs_faq2.html#placement-delete
John Dibling
@Philipp: That's an ambiguity in the current standard, but you should understand it as placement-new being separate from the others. Only pointers obtained from (non-placement-)new—where you've followed all the relevant rules (including that manual dtor calls match up with placement-new and other object lifetime rules)—can be deleted.
Roger Pate
@Philipp: *placement-new* is a way of calling a constructor, and the reverse operation is calling the destructor, not calling `delete`. `void foo( void * buffer ) { new (buffer) Type; ... ; static_cast<Type*>(buffer)->~Type(); }`
David Rodríguez - dribeas
A: 

There is one corner case, which I can think of, where it is OK to delete the local object manually.

struct A{
    A(){}
    int x;
    ~A(){}
};

int main(){
    char buf[sizeof(A)];
    A *p = new(buf)A();
    p->~A();
}
Chubsdad
There is no `delete` call here?
John Dibling
@Chubsdad but you NOT DELETING you are destroying in that case.
There is nothing we can do
Not sure why it is downvoted. The OP never asked about using delete. It was about deleting the object.
Chubsdad
@Chubsdad: I get what you're saying, but your code doesn't delete the object. There is no way your response is relevant to the OP's question. Not my downvote, JSYK.
John Dibling
@Chubsdad: If "the OP never asked about using delete", then why does he say "deleting" twice and use "delete" 3 times in his code?
Roger Pate
A: 

If you need to know that ownership is transferred, then don't use raw pointers. Use smart pointers, such as std::auto_ptr (Boost and C++0x have many more) which make the transfer of ownership explicit and additionally convey how to destroy the objects (for auto_ptr this means delete):

struct Example {
  Example(std::auto_ptr<T> parent, std::auto_ptr<TObject> left,
          std::auto_ptr<T> right)
  : _parent (parent), _left (left), _right (right)
  {}

private:
  std::auto_ptr<T> _parent, _left, _right;
};

You could still store raw pointers, if you really insist, by using auto_ptr's release method and writing a copy ctor, destructor, and assignment operator for Example (the Rule of Three).

Roger Pate
A: 

Use references instead of pointers.