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!
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
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;
};
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.
Related
I have a simple C++ code, but I don't know how to use the destructor:
class date {
public:
int day;
date(int m)
{
day =m;
}
~date(){
cout << "I wish you have entered the year \n" << day;
}
};
int main()
{
date ob2(12);
ob2.~date();
cout << ob2.day;
return 0;
}
The question that I have is, what should I write in my destructor code, that after calling the destructor, it will delete the day variable?
Rarely do you ever need to call the destructor explicitly. Instead, the destructor is called when an object is destroyed.
For an object like ob2 that is a local variable, it is destroyed when it goes out of scope:
int main()
{
date ob2(12);
} // ob2.~date() is called here, automatically!
If you dynamically allocate an object using new, its destructor is called when the object is destroyed using delete. If you have a static object, its destructor is called when the program terminates (if the program terminates normally).
Unless you create something dynamically using new, you don't need to do anything explicit to clean it up (so, for example, when ob2 is destroyed, all of its member variables, including day, are destroyed). If you create something dynamically, you need to ensure it gets destroyed when you are done with it; the best practice is to use what is called a "smart pointer" to ensure this cleanup is handled automatically.
You do not need to call the destructor explicitly. This is done automatically at the end of the scope of the object ob2, i.e. at the end of the main function.
Furthermore, since the object has automatic storage, its storage doesn’t have to be deleted. This, too, is done automatically at the end of the function.
Calling destructors manually is almost never needed (only in low-level library code) and deleting memory manually is only needed (and only a valid operation) when the memory was previously acquired using new (when you’re working with pointers).
Since manual memory management is prone to leaks, modern C++ code tries not to use new and delete explicitly at all. When it’s really necessary to use new, then a so-called “smart pointer” is used instead of a regular pointer.
You should not call your destructor explicitly.
When you create your object on the stack (like you did) all you need is:
int main()
{
date ob2(12);
// ob2.day holds 12
return 0; // ob2's destructor will get called here, after which it's memory is freed
}
When you create your object on the heap, you kinda need to delete your class before its destructor is called and memory is freed:
int main()
{
date* ob2 = new date(12);
// ob2->day holds 12
delete ob2; // ob2's destructor will get called here, after which it's memory is freed
return 0; // ob2 is invalid at this point.
}
(Failing to call delete on this last example will result in memory loss.)
Both ways have their advantages and disadvantages. The stack way is VERY fast with allocating the memory the object will occupy and you do not need to explicitly delete it, but the stack has limited space and you cannot move those objects around easily, fast and cleanly.
The heap is the preferred way of doing it, but when it comes to performance it is slow to allocate and you have to deal with pointers. But you have much more flexibility with what you do with your object, it's way faster to work with pointers further and you have more control over the object's lifetime.
Only in very specific circumstances you need to call the destructor directly. By default the destructor will be called by the system when you create a variable of automatic storage and it falls out of scope or when a an object dynamically allocated with new is destroyed with delete.
struct test {
test( int value ) : value( value ) {}
~test() { std::cout << "~test: " << value << std::endl; }
int value;
};
int main()
{
test t(1);
test *d = new t(2);
delete d; // prints: ~test: 2
} // prints: ~test: 1 (t falls out of scope)
For completeness, (this should not be used in general) the syntax to call the destructor is similar to a method. After the destructor is run, the memory is no longer an object of that type (should be handled as raw memory):
int main()
{
test t( 1 );
t.~test(); // prints: ~test: 1
// after this instruction 't' is no longer a 'test' object
new (&t) test(2); // recreate a new test object in place
} // test falls out of scope, prints: ~test: 2
Note: after calling the destructor on t, that memory location is no longer a test, that is the reason for recreation of the object by means of the placement new.
In this case your destructor does not need to delete the day variable.
You only need to call delete on memory that you have allocated with new.
Here's how your code would look if you were using new and delete to trigger invoking the destructor
class date {
public: int* day;
date(int m) {
day = new int;
*day = m;
}
~date(){
delete day;
cout << "now the destructor get's called explicitly";
}
};
int main() {
date *ob2 = new date(12);
delete ob2;
return 0;
}
Even though the destructor seems like something you need to call to get rid of or "destroy" your object when you are done using it, you aren't supposed to use it that way.
The destructor is something that is automatically called when your object goes out of scope, that is, when the computer leaves the "curly braces" that you instantiated your object in. In this case, when you leave main(). You don't want to call it yourself.
You may be confused by undefined behavior here. The C++ standard has no rules as to what happens if you use an object after its destructor has been run, as that's undefined behavior, and therefore the implementation can do anything it likes. Typically, compiler designers don't do anything special for undefined behavior, and so what happens is an artifact of what other design decisions were made. (This can cause really weird results sometimes.)
Therefore, once you've run the destructor, the compiler has no further obligation regarding that object. If you don't refer to it again, it doesn't matter. If you do refer to it, that's undefined behavior, and from the Standard's point of view the behavior doesn't matter, and since the Standard says nothing most compiler designers will not worry about what the program does.
In this case, the easiest thing to do is to leave the object untouched, since it isn't holding on to resources, and its storage was allocated as part of starting up the function and will not be reclaimed until the function exits. Therefore, the value of the data member will remain the same. The natural thing for the compiler to do when it reads ob2.day is to access the memory location.
Like any other example of undefined behavior, the results could change under any change in circumstances, but in this case they probably won't. It would be nice if compilers would catch more cases of undefined behavior and issue diagnostics, but it isn't possible for compilers to detect all undefined behavior (some occurs at runtime) and often they don't check for behavior they don't think likely.
#include <iostream>
struct ABC{
int A;
ABC(int i = 1) : A(i) {}
~ABC() {
std::cout << A << std::endl;
}
void destruct() {
delete this;
}
};
int main() {
ABC A1(2);
A1.destruct();
return 0;
}
Output:
2
2
I have this code in which I'm trying to manually delete structure variable. Doing so, I realized the destructor gets called twice here. Why is this happening? Why isn't it getting deleted when destruct() is called?
The delete this call causes undefined behaviour, which means that anything at all can happen.
delete may only be used for objects created by new.
For automatic objects with a non-trivial destructor (e.g. your A1), it is not possible to "destroy them early" unless you also create another ABC in the same place before the scope ends. In other words you can't "turn off" the destruction process that occurs when the scope ends.
Why isn't [my object] getting deleted when destruct() is called?
When an object gets destructed in C++, it does not mean that the object disappears. It means that the clean-up code from the destructor gets executed, and that any access to the object's members from that point on is invalid.
When you call destruct() you try to free object's memory by calling delete. This is undefined behavior in itself, because you have not allocated the object with new. This call causes the first printout.
However, since your object is in automatic memory, C++ is required to call its destructor when the object gets out of scope. This is the call that causes the second printout.
Note: You can fix your code by allocating A1 in dynamic memory:
int main() {
ABC *A1 = new ABC(2);
A1->destruct();
return 0;
}
Now you get a single printout (demo). However, the practice of hiding delete in a member function is questionable.
This is RAII working plus you committing suicide on an object. Calling the destructor on an object is almost always wrong! And calling the destructor twice is always wrong, as it invokes undefined behaviour.
You have to understand that C++ is handling memory for you, if you just let it:
struct Foo{};
int main() {
Foo f; // automatic storage, gets destroyed
// when object gets out of scope
Foo* g = new Foo(); // heap allocated
delete g; // only here you have to delete
}
Just remember: Do not delete anything that you did not create via new (thanks to Mike Vine for the comment). And do not use (naked) heap allocation unless you need to.
Two points to consider here :-
1) Destructor for stack objects will always be called when they go out of scope. So no need to worry for their deallocation.
2) You cannot & should not use delete on the object allocated on stack. In general, you should not use delete this as long as you are not sure that this will be executed only as a consequence of deleting heap objects and after that you are not referring to that object.
I have a simple C++ code, but I don't know how to use the destructor:
class date {
public:
int day;
date(int m)
{
day =m;
}
~date(){
cout << "I wish you have entered the year \n" << day;
}
};
int main()
{
date ob2(12);
ob2.~date();
cout << ob2.day;
return 0;
}
The question that I have is, what should I write in my destructor code, that after calling the destructor, it will delete the day variable?
Rarely do you ever need to call the destructor explicitly. Instead, the destructor is called when an object is destroyed.
For an object like ob2 that is a local variable, it is destroyed when it goes out of scope:
int main()
{
date ob2(12);
} // ob2.~date() is called here, automatically!
If you dynamically allocate an object using new, its destructor is called when the object is destroyed using delete. If you have a static object, its destructor is called when the program terminates (if the program terminates normally).
Unless you create something dynamically using new, you don't need to do anything explicit to clean it up (so, for example, when ob2 is destroyed, all of its member variables, including day, are destroyed). If you create something dynamically, you need to ensure it gets destroyed when you are done with it; the best practice is to use what is called a "smart pointer" to ensure this cleanup is handled automatically.
You do not need to call the destructor explicitly. This is done automatically at the end of the scope of the object ob2, i.e. at the end of the main function.
Furthermore, since the object has automatic storage, its storage doesn’t have to be deleted. This, too, is done automatically at the end of the function.
Calling destructors manually is almost never needed (only in low-level library code) and deleting memory manually is only needed (and only a valid operation) when the memory was previously acquired using new (when you’re working with pointers).
Since manual memory management is prone to leaks, modern C++ code tries not to use new and delete explicitly at all. When it’s really necessary to use new, then a so-called “smart pointer” is used instead of a regular pointer.
You should not call your destructor explicitly.
When you create your object on the stack (like you did) all you need is:
int main()
{
date ob2(12);
// ob2.day holds 12
return 0; // ob2's destructor will get called here, after which it's memory is freed
}
When you create your object on the heap, you kinda need to delete your class before its destructor is called and memory is freed:
int main()
{
date* ob2 = new date(12);
// ob2->day holds 12
delete ob2; // ob2's destructor will get called here, after which it's memory is freed
return 0; // ob2 is invalid at this point.
}
(Failing to call delete on this last example will result in memory loss.)
Both ways have their advantages and disadvantages. The stack way is VERY fast with allocating the memory the object will occupy and you do not need to explicitly delete it, but the stack has limited space and you cannot move those objects around easily, fast and cleanly.
The heap is the preferred way of doing it, but when it comes to performance it is slow to allocate and you have to deal with pointers. But you have much more flexibility with what you do with your object, it's way faster to work with pointers further and you have more control over the object's lifetime.
Only in very specific circumstances you need to call the destructor directly. By default the destructor will be called by the system when you create a variable of automatic storage and it falls out of scope or when a an object dynamically allocated with new is destroyed with delete.
struct test {
test( int value ) : value( value ) {}
~test() { std::cout << "~test: " << value << std::endl; }
int value;
};
int main()
{
test t(1);
test *d = new t(2);
delete d; // prints: ~test: 2
} // prints: ~test: 1 (t falls out of scope)
For completeness, (this should not be used in general) the syntax to call the destructor is similar to a method. After the destructor is run, the memory is no longer an object of that type (should be handled as raw memory):
int main()
{
test t( 1 );
t.~test(); // prints: ~test: 1
// after this instruction 't' is no longer a 'test' object
new (&t) test(2); // recreate a new test object in place
} // test falls out of scope, prints: ~test: 2
Note: after calling the destructor on t, that memory location is no longer a test, that is the reason for recreation of the object by means of the placement new.
In this case your destructor does not need to delete the day variable.
You only need to call delete on memory that you have allocated with new.
Here's how your code would look if you were using new and delete to trigger invoking the destructor
class date {
public: int* day;
date(int m) {
day = new int;
*day = m;
}
~date(){
delete day;
cout << "now the destructor get's called explicitly";
}
};
int main() {
date *ob2 = new date(12);
delete ob2;
return 0;
}
Even though the destructor seems like something you need to call to get rid of or "destroy" your object when you are done using it, you aren't supposed to use it that way.
The destructor is something that is automatically called when your object goes out of scope, that is, when the computer leaves the "curly braces" that you instantiated your object in. In this case, when you leave main(). You don't want to call it yourself.
You may be confused by undefined behavior here. The C++ standard has no rules as to what happens if you use an object after its destructor has been run, as that's undefined behavior, and therefore the implementation can do anything it likes. Typically, compiler designers don't do anything special for undefined behavior, and so what happens is an artifact of what other design decisions were made. (This can cause really weird results sometimes.)
Therefore, once you've run the destructor, the compiler has no further obligation regarding that object. If you don't refer to it again, it doesn't matter. If you do refer to it, that's undefined behavior, and from the Standard's point of view the behavior doesn't matter, and since the Standard says nothing most compiler designers will not worry about what the program does.
In this case, the easiest thing to do is to leave the object untouched, since it isn't holding on to resources, and its storage was allocated as part of starting up the function and will not be reclaimed until the function exits. Therefore, the value of the data member will remain the same. The natural thing for the compiler to do when it reads ob2.day is to access the memory location.
Like any other example of undefined behavior, the results could change under any change in circumstances, but in this case they probably won't. It would be nice if compilers would catch more cases of undefined behavior and issue diagnostics, but it isn't possible for compilers to detect all undefined behavior (some occurs at runtime) and often they don't check for behavior they don't think likely.
How does C++ ensure that destructors are called for stack assigned objects? What happens to the destructor function (or a pointer to it) when I assign dynamic memory as follows:
class MyClass {
public:
~MyClass()
{
std::cout<<"Destructor called."<<std::endl;
}
MyClass()
{
std::cout<<"Constructor called."<<std::endl;
}
};
....................................................................
//Limit scope for example
{
MyClass instance;
}
The constructor and destructor are both called. What's going on here?
The compiler inserts a call to the destructor for the object at an appropriate position.
You wouldn't wonder why this
{
int i;
}
creates and destroys i automatically, would you? C++ does a lot to allow you to create types that behave just like built-in types. And just like with built-in types, in C++ (other than in, say, Java or C#), this
{
MyClass instance;
}
doesn't just define a reference that might be bound to null or some actual object. It creates an actual object.
Object creation comes in two steps: First (upon entering the scope) the raw memory is provided. Then (when the object definition is encountered) the constructor is called. For built-in types no constructor is called. If you don't initialize a built-in variable, it has a random value. (Actually it's whatever the bit pattern was at the memory provided in step #1.) Object deletion, too, comes in two steps: First, the destructor is called (again, not for built-ins), then the memory is returned to the run-time system.
(Note that providing and deleting memory for stack variables usually is as cheap as incementing/decrementing a register.)
The constructor is called as soon as the variable is created. As for the destructor, the compiler emits code at the end of scope to call the destructor. To get a feel for this, try using a 'goto', or switch/case construct to prematurely exit the scope, and watch the compiler complain.
Yes, both the constructor and destructor are called. And even more important:
{
MyClass instance;
throw "exception";
}
in this example, the destructor is also called. That is why I always prefer to allocate my objects on stack (or at least wrap the dynamic allocations with a stack-allocated guardians).
The constructor is called because you're creating an object. The destructor is called because your cleaning up that object. Remember, in C++, objects declared on the stack are automatically cleaned up when their containing scope goes away.
Well, it did not call the destructor just after constructor.
It calls it when it about to terminate the programme.
int main() {
MyClass obj;
cout<<"testing....1"<<endl;
cout<<"testing....2"<<endl;
return 0;
}
ans:
Constructor called.
testing....1
testing....2
Destructor called.
I'm porting a bit of an old code from C to C++. The old code uses object-like semantics, and at one point separates object destruction from freeing the now-unused memory, with stuff happening in between:
Object_Destructor(Object *me) { free(me->member1), free(me->member2) }
ObjectManager_FreeObject(ObjectManager *me, Object *obj) { free(obj) }
Is the above functionality possible in C++ using the standard destructor (~Object) and a subsequent call to delete obj? Or, as I fear, doing that would call the destructor twice?
In the particular case, the operator delete of Object is overridden as well. Is the definition I've read elsewhere ("when operator delete is used, and the object has a destructor, the destructor is always called) correct in the overridden operator case?
The delete operator is used to free memory, it doesn't change whether the destructor is called or not. First the destructor is called, and only after that is the delete operator used to deallocate the memory.
In other words it's not possible to achieve the semantics you're aiming at with C++'s destructors and delete operators.
Sample:
#include <iostream>
#include <new>
using namespace std;
struct foo {
~foo() { cout << "destructor\n"; }
void operator delete(void* p) {
cout << "operator delete (not explicitly calling destructor)\n";
free(p);
cout << "After delete\n";
}
};
int main()
{
void *pv = malloc(sizeof(foo));
foo* pf = new (pv) foo; // use placement new
delete pf;
}
Output:
destructor
operator delete (not explicitly calling destructor)
After delete
Overloaded delete still calls destructor implicitly before it starts executing as opposed to placement delete (but placement delete is not supposed to be called directly).
So if you are going to "delete" object, do not destroy it in advance you will have destructor called twice. However explicit destruction is due if object was created with placement new (but in that case you do not destroy object using delete)
What sort of stuff happens between the destruction of the object and the freeing of the object's memory? If it has nothing to do with the object, then you should be able to delete the object where the destructor appears. If it does, well, I'd examine that very carefully, because it sounds like a bad idea.
If you have to reproduce the semantics, have a member function that releases all the resources, and use that instead of the destruct function. Make sure that function can be called more than once safely, and include it in the C++ destructor just to be sure.
I absolutely don't get why people say it's impossible.
Decoupling initialization from construction and zeroization (tm) from destruction is actually extremely simple.
class Clike
{
public:
Clike() : m_usable(true) {}
void clear(); // performs clean up then sets m_usable to false
~Clike() { if (m_usable) this->clear(); }
private:
bool m_usable;
// real variables
};
Then you can use it like so:
Clike* c = new Clike();
c->clear(); // performs cleanup
// stuff
delete c;
Actually, since destructors should never throw and do not return anything, it is not unusual at all that the cleanup and the destruction be separated so that the cleanup operation may report errors. Especially for complicated beasts like DB Connections etc...
While this is not a 'destructor' thing, it sure works, and so the C-code presented is actually perfectly reproducible without those fancy placement new etc...
You can separate destruction from deletion, but you probably don't really want to.
If you allocate the memory with new char[] or malloc, and then call placement new, then you can separate destruction (which you do by directly calling the destructor) from deletion (or free). But then you're no longer calling the class's overloaded operator delete, instead you're calling delete[] on the char array (or free).
If you call delete via a pointer to your class (the one you overloaded operator delete for), then that class's destructor will be called. So there is no way to separate them in the sense you ask for, of calling delete without the destructor.
No, it is not possible.
delete calls the destructor.
You will need to work out some kind of logic to ensure that Stuff happens in the right order.
Have a look at the std::allocators for the implementation. The answer is 'yes, they may be decoupled'. It's quite easy to do, it just not seen very often.
It sounds like you might want a placement new. On the other hand, it also sounds like your code is getting pretty hairy. It might be time for some heavy refactoring.
The destructor is coupled to delete and you can't call it twice because you can't explicitely call the destructor (or at least it is highly unusual and uncommon, I've never seen it).
However, just make object_destructor() a member function and call it explicitely (and usually it's good style to make it safe for being called twice. In your case however, calling twice is okay anyway, because calling free() with a NULL pointer is legal, so the alternate version of object_destructor is just to highlight how it could be done.
CLASS A {
object_destructor() { free(this->member1); free(this->member2); }
alternate_version_of_object_destructor() {
if (this->member1) { free(this->member1); this->member1= NULL; }
if (this->member2) { free(this->member2); this->member2= NULL; } }
~A() { /* do nothing or just call this->object_destructor() for safety */ }
}
foo() {
A *pa= new A;
pa->object_destructor(); /* member cleanup */
delete pa; /* free object memory */
}