Reputation: 110
So I'm a beginner trying to get to grips with operator new. What's wrong with my destructor?
class arr{
public:
arr(){
pool=::operator new(100*sizeof(double));
}
~arr(){
::operator delete(pool);
}
void* pool;
};
int main()
{
arr a;
a.~arr(); //If I comment this out it's ok.
void* pool2=::operator new(100*sizeof(double)); //Works
::operator delete(pool2); //Fine.
system("pause");
return 0;
}
Leaving a.~arr(); in gives me this error:
Debug assertion failed! File: dbgdel.cpp line: 52
Expression: _BLOCK_TYPE_IS_VALID(pHead->nBlockUse)
I can't see why pool2 works fine but using the class gives me problems. Also the error only pops up after the system "pauses", which is after a.~arr() is called???
Thanks!
Upvotes: 1
Views: 1416
Reputation: 224039
The problem is that you explicitly invoke the destructor on a
(a.~arr()
), while the destructor will already be invoked automatically when a
goes out of scope at the end of main()
. When the destructor is called for the second time, it is called on an already destructed object. Technically, this leads to Undefined Behavior (which is a way to say that any result will be fine according to the C++ standard). In practice this code will likely just execute the destructor again, passing the address stored in the memory location that used to be a.pool
to the ::operator delete()
(which might or might not be what the constructor stored there), which is caught by the Debug runtime.
What you should do instead if you want a
to be deleted in the middle of main()
is to introduce an additional scope:
int main()
{
{
arr a;
} //a will be deleted here
// rest of main
}
Another way would be to not to use an automatic object, but a dynamic one, for which you can set a lifetime.
But there's another problem with your code, which you didn't ask about, but which I nevertheless feel a need to point out:
Your class urgently needs a copy constructor and a assignment operator. (At the very least, declare them private
in order to disallow copying.) As per the Rule Of Three, the fact that you need a destructor should give you a hint that the other two are needed as well.
You can avoid all the hassle by not attempting to manually manage dynamically allocated memory. Instead use a type which does this for you:
class arr{
public:
arr() : pool(100*sizeof(double)) {
}
// ~arr() // not needed any longer
std::vector<char> pool;
};
Upvotes: 6
Reputation: 10473
you don't need to call destructor for objects created on stack. The variable 'a' is on stack and will be deleted automatically when out of scope.
Upvotes: 0
Reputation: 5425
Well, at a glance, you should not be explicitly calling the destructor. Instead use scoping to force a out of scope and call the destructor.
int main()
{
{
arr a;
} //This calls destructor of a
//Rest of code
}
Otherwise the destructor of a gets called twice: once when you call it and again when a goes out of scope.
EDIT:
Here ya go.
http://www.parashift.com/c++-faq-lite/dtors.html
Upvotes: 7