Just started learning C++ and I'm confused on how to program a deconstructor. So far I understand that a deconstructor is called whenever an object is destroyed, which from my understanding is when the program ends and C++ automatically destroys all objects. Does this just mean that I should just re-intialize all variables back to what they originally were?
So is this what I should have:
/*In the Header file*/
List();
~List();
//Other function prototypes go here
/*In the Implementation file*/
List::List()
{
head = NULL;
tail = NULL;
count = 1;
}
List::~List
{
head = NULL;
tail = NULL;
count = 1;
}
//Other function bodies go here
No. The destructor is for deallocating/cleaning up any resources that the object might be using. For instance file handles need to be closed, UI resources need to be released back to the system, memory that you have newed needs to be deleteed.
In your example count seems like an int, so you don't need to do anything for that as the memory for that is a part of the object being destroyed, but if you have allocated memory for your list you will have to deallocated it in the destructor. Depending on how you have constructed the list you might want to iterate through the list and deallocate each node.
To clear up one misconception, the destructor is called any time an object goes out of scope (a local variable hits the end of the code block in which it was created). If an object was created in global scope (outside of a function) it will be destroyed at program exit. Think of this as a big set of braces around the whole program.
void function(object a)
{
object b;
int x = 0;
while (x < 10)
{
object c;
// La la la Doing stuff.
} // c destroyed here. It will be created and destroyed for each run through the loop
a = b;
} //b destroyed here
// a also destroyed here, so watch out passing things into functions if you want them
// back changed.
or when it is manually destroyed with the delete command
object * d = new object();
// la la la doing stuff
delete d;
Since d was manually created, it must be manually destroyed. Watch out C# and Java people.
What do you need to do in a destructor?
Put everything away. Don't waste your time setting values back to their defaults. They won't be around long enough to appreciate the gesture. But if you opened a file, and still have it open, close it. If you newed other objects, delete them. If you have a mutex locked, unlock it. If you are managing threads, you probably want to notify the threads and wait for them to finish before finishing. But do it with a time-out so you don't hang on a stuck thread.
While we're on the topic, read this: What is The Rule of Three?
Put simply The Rule of Three means if you have a destructor, a copy constructor or an assignment operator (operator=), you almost certainly require all three. A lot of time you'll see people getting odd memory errors because they didn't obey the Rule of Three. Don't be that guy.
When you have The Rule of Three down, go looking for the Rule of Five.
How this applies to the OP:
List::~List
{
head = NULL; //very probably need to delete this pointer
tail = NULL; //and possibly this one
count = 1; // don't need this at all
}
So it should probably look like:
List::~List
{
if (head != NULL)
{
delete head; // This should start a chain reaction deleting all of the linked
// items in the list, ensuring that they have all been freed
}
}
In addition, the OP should have a copy constructor and an assignment operator that make sure that when the List is deleted it doesn't also obliterate the data of any copies of the list.
It is called destructor not deconstructor
A destructor code is generally defines how you may end the life of an instance of a class.
Usually this will include memory deallocation or freeing as well as resource freeing 'closing a file handle', unlocking a synchroniser, it might also include more complicated stuff like interrupting a thread to end it's life if this thread life cycle is inside the class.. it might have more than that like notifying about the destruction of a class to whomever have assigned for a notification .. there is a lot of code that might be required when you end an instance of a class without a destructor the encapsulation of OOP would have suffered
Last note in c++ the new, and delete reserved words are memory allocators that use the constructor/destructor of an instance of an object
I hope it is clear enough
Related
I have the following code and I get stack overflow error can anyone please explain me What's wrong here. from my understanding this pointer points to current object so why I cant delete it in a destructor;
class Object
{
private:
static int objCount;
public:
int getCount()
{
int i =10;
return i++;
}
Object()
{
cout<< "Obj Created = "<<++objCount<<endl;
cout <<endl<<this->getCount()<<endl;
}
~Object()
{
cout<<"Destructor Called\n"<<"Deleted Obj="<<objCount--<<endl;
delete this;
}
};
int Object::objCount = 0;
int _tmain(int argc, _TCHAR* argv[])
{
{
Object obj1;
}
{
Object *obj2 = new Object();
}
getchar();
return 0;
}
You're doing delete this; in your class's destructor.
Well, delete calls the class's destructor.
You're doing delete this; in your class's destructor.
...
<!<!<!Stack Overflow!>!>!>
(Sorry guys I feel obliged to include this... this might probably spoil it sorrrryyyy!
Moral of the boring story, don't do delete this; on your destructor (or don't do it at all!)
Do [1]
Object *obj = new Object();
delete obj;
or much better, just
Object obj;
[1]#kfsone's answer more accurately points out that the stack overflow was actually triggered by obj1's destructor.
'delete this' never makes sense. Either you're causing an infinite recursion, as here, or you're deleting an object while it is still in use by somebody else. Just remove it. The object is already being deleted: that's why you're in the destructor.
The crash you are having is because of the following statement:
{
Object obj1;
}
This allocates an instance of "Object" on the stack. The scope you created it in ends, so the object goes out of scope, so the destructor (Object::~Object) is invoked.
{
Object obj1;
// automatic
obj1.~Object();
}
This means that the next instruction the application will encounter is
delete this;
There are two problems right here:
delete calls the object's destructor, so your destructor indirectly calls your destructor which indirectly calls your destructor which ...
After the destructor call, delete attempts to return the object's memory to the place where new obtains it from.
By contrast
{
Object *obj2 = new Object();
}
This creates a stack variable, obj2 which is a pointer. It allocates memory on the heap to store an instance of Object, calls it's default constructor, and stores the address of the new instance in obj2.
Then obj2 goes out of scope and nothing happens. The Object is not released, nor is it's destructor called: C++ does not have automatic garbage collection and does not do anything special when a pointer goes out of scope - it certainly doesn't release the memory.
This is a memory leak.
Rule of thumb: delete calls should be matched with new calls, delete [] with new []. In particular, try to keep new and delete in matching zones of authority. The following is an example of mismatched ownership/authority/responsibility:
auto* x = xFactory();
delete x;
Likewise
auto* y = new Object;
y->makeItStop();
Instead you should prefer
// If you require a function call to allocate it, match a function to release it.
auto* x = xFactory();
xTerminate(x); // ok, I just chose the name for humor value, Dr Who fan.
// If you have to allocate it yourself, you should be responsible for releasing it.
auto* y = new Object;
delete y;
C++ has container classes that will manage object lifetime of pointers for you, see std::shared_ptr, std::unique_ptr.
There are two issues here:
You are using delete, which is generally a code smell
You are using delete this, which has several issues
Guideline: You should not use new and delete.
Rationale:
using delete explicitly instead of relying on smart pointers (and automatic cleanup in general) is brittle, not only is the ownership of a raw pointer unclear (are you sure you should be deleting it ?) but it is also unclear whether you actually call delete on every single codepath that needs it, especially in the presence of exceptions => do your sanity (and that of your fellows) a favor, don't use it.
using new is also error-prone. First of all, are you sure you need to allocate memory on the heap ? C++ allows to allocate on the stack and the C++ Standard Library has containers (vector, map, ...) so the actual instances where dynamic allocation is necessary are few and far between. Furthermore, as mentioned, if you ever reach for dynamic allocation you should be using smart pointers; in order to avoid subtle order of execution issues it is recommend you use factory functions: make_shared and make_unique (1) to build said smart pointers.
(1) make_unique is not available in C++11, only in C++14, it can trivially be implemented though (using new, of course :p)
Guideline: You shall not use delete this.
Rationale:
Using delete this means, quite literally, sawing off the branch you are sitting on.
The argument to delete should always be a dynamically allocated pointer; therefore should you inadvertently allocate an instance of the object on the stack you are most likely to crash the program.
The execution of the method continues past this statement, for example destructors of local objects will be executed. This is like walking on the ghost of the object, don't look down!
Should a method containing this statement throw an exception or report an error, it is difficult to appraise whether the object was successfully destroyed or not; and trying again is not an option.
I have seen several example of usage, but none that could not have used a traditional alternative instead.
I've run into a problem while working with the built-in pointers in C++. When my program terminates, my classes destructors are all called. I have a data class, a queue class, and another data class which incorporates uses the queue as follows (mind the rough coding on the fly):
class Data {
int x;
}
class Queue {
class Node {
Data* x;
}
Node* head;
}
class C1 {
Queue q;
}
class C1Queue{
class Node {
C1* c;
}
Node* head;
}
I also have another Queue, q2, that does not reside in an object. I load both queues from a file, so I say something along the lines of (assuming cQueue is a C1Queue):
Data *d = new Data(0);
q2->pushBack(d);
C1 c = new C1();
cQueue->pushBack(c->pushBack(d));
As you can see, I have both a queue (q2) holding pointers to each of the data, as well as an object with a queue holding pointers to the same data as q2 is holding.
Now, when my program terminates I want all the data to be deallocated. However, when the objects are being deallocated, either q2 is deallocated first, and when the C1 objects are to be deallocated, then they deallocate their queues, which then deletes the same data as q2 just deleted. Or the other case is that the objects are deallocated first (I'm not sure which ordering occurs), and then q2 is deallocated and it runs into already deleted memory.
So the problem is that the memory space is being deleted twice, which is not good. Once memory has been deleted, it is released to other programs to use, so deleting that memory space again will result in a seg fault.
Maybe I am missing something here, but I can't figure out how to do this without having a special type of pointer (I cannot use a special type of pointer).
The only way I can think of is to block the C1 object from deallocating it's queue but deallocating the rest of itself, but I don't know how to do that. If someone could help me with this then I would much appreciate it.
Since you are (apparently) prevented from using niceties like std::shared_ptr, you can try one of the following three remedies:
Manual refcounting. Enforce that every time a Data is pushed onto a queue that its refcount be incremented, and decrement the refcount as a Queue is cleaned up. When the refcount hits zero, delete this (but make sure you always allocate Datas on the heap!)
Designate an object to "own" the Data elements. Only that object can destroy Data (you may even enforce this with a private destructor and a friend class). You might need more than one of these. (If you refcount this proxy, this becomes a poor man's std::shared_ptr).
Make your Datas copyable, and just do everything with brand new objects. This works if it's a small amount of data that doesn't need to stay in sync (for example, a Point2D class holding two integers).
I'm wonder to know is it possible to delete an object through destructor method?
Constructor and destructor of my class:
class cal
{
public:
cal()
{
days = 0;
day = 1;
month = 1;
year = 1300;
leap = true;
};
~cal()
{
delete this;
}
}*calendar = new cal;
How can I delete this pointer through class?
P.S
I forgot to write the following code
cal *calandar = new cal[];
I want to use it in heap not stack
I want to use this class (objects) frequently (many of that object) imagine how many time should I write delete and it make hard understanding, troubleshooting and tracing codes I want them to been destroyed automatically (in heap)
I used following code in my class when I exec "delete[] calendar" it reduce my rams occupied (amount of ram that is used) does it work properly (destroy all objects) by exiting program? Because I use GNU/Linus and it destructs all objects with or without that lines I'm concern about leaking in windows
void DisposeObject() { delete this; }
No. By the time the destructor is called, the object is already being destroyed, so delete this is not valid.
The behaviour is undefined, but most likely it will call the destructor recursively, leading to a stack overflow.
You can write the code like this:
class cal
{
public:
cal()
{
};
~cal()
{
}
void DisposeObject()
{
delete this;
}
}
And it will call your destructor.
You should not call delete this from your destructor since it will call the destructor recursively, possibly leading to a stack overflow. Anyway, the code you wrote suffers from undefined behavior.
Refer to this question for in-depth discussion: Is delete this allowed?
I`m wonder to know is it possible to delete an object through destructor method
Even supposing this was valid - The problem is that nothing would ever call the destructor, so this would never have an effect. The destructor is called when the calling code deletes the object, which in turn can delete any internal objects as needed.
In your case, it doesn't look like you need to do anything in your destructor, however, as you don't have any resources being allocated that need to be explicitly deleted (at least in what you're showing).
I was wondering, if I create an object in main using the new keyword, then set that object (pointer) to be pointed to by a member of another class, setting the original pointer to null, where would I delete the allocated memory? I could do it in the second class's destructor but what if that object wasn't dynamically allocated?
Some code as an example:
World world;
Player* newPlayer = new Player("Ted");
world.setPlayer(newPlayer);
newPlayer = 0;
So now the 'player' member variable in World is pointing to the memory allocated by newPlayer and newPlayer is pointing to null. How should I deallocate this memory when I'm done with the World object?
This kind of complexity is why you should try to avoid raw pointers in C++. Smart pointers exist to solve this kind of problem, and save you the headache of manually tracking who has ownership of an object and when to delete it.
For example:
typedef boost::shared_ptr<Player> sp_Player;
struct World {
sp_Player player;
World(sp_Player p) : player(p) {}
};
sp_Player newPlayer = new Player("Ted");
World world;
world.setPlayer(newPlayer);
// Object is now automatically deleted at the correct time!
As noted in other answers it is easier to use smart pointers however in this case you can put the delete elsewhere.
If all players are passed to a World then World can deal with the memory - every time a World is destructed or when a different player is set the the Player that World holds has to be deleted. Also no Player should be destroyed anywhere else or otherwise it could be destroyed twice. However in this case I would make all Players be constructed by a method in World to keep it clear who owns the memory management and keep the same class creating and destroying the Player objects
Some very incomplete code is (note how the smart pointer code is much less and I think covers all cases - this does not)
class World
{
Player *p;
...
}
World() : p(nullptr) {
...
}
~World() {
delete p;
}
void World setPlayer( Palyer *aP ) {
if ( p != aP) {
delete p;
}
p = aP;
....
}
Player* World::createPlayer(std::string const& name){
return new Player(name);
}
Note = Player(name) creates a Playeobject on the stack and that is not managed in your code by new and delete - and might be the best solution here.
Also need to deal with operator= and the copy constructor (for the latter best to stop it ever being called or it will need to duplicate the Player object so deleting the Original World and the copy will not both attempt to delete the same Player)
There is no absolute answer. The question is: why are you allocating
the object dynamically to begin with? Once you've answered this, it's
usually obvious where it should be deleted.
From the names of your objects, for example, I'd guess that world owns
everything; that it decides the lifetime of players, etc. In which
case, it should be responsible for the delete. As for the possibiltiy
of allocating a Person on the stack: don't do that. Given that
Person probably has a definitely lifetime which doesn't correspond
to a block in a function (otherwise, why allocate it dynamically to
begin with), it doesn't make sense to declare local variables of that
type.
You just need to call delete when you are finished. To avoid the need for this though look into making use of shared pointers as they will relieve you of the need to do this.
Edit: To answer your comment, where you call delete depends on your application but ensure that you
Dont delete it before you have allocated it.
Dont delete it until you are sure nothing else needs to access it.
A possible place would be in the destructor of your World object, but it is impossible to say without knowing details of the rest of your application. This is why boost::shared_ptr is preferable.
new should always followed by delete. If you set the pointer to point to some other object without freeing up the memory it will result in dangling pointer
Basic Question: when does a program call a class' destructor method in C++? I have been told that it is called whenever an object goes out of scope or is subjected to a delete
More specific questions:
1) If the object is created via a pointer and that pointer is later deleted or given a new address to point to, does the object that it was pointing to call its destructor (assuming nothing else is pointing to it)?
2) Following up on question 1, what defines when an object goes out of scope (not regarding to when an object leaves a given {block}). So, in other words, when is a destructor called on an object in a linked list?
3) Would you ever want to call a destructor manually?
1) If the object is created via a pointer and that pointer is later deleted or given a new address to point to, does the object that it was pointing to call its destructor (assuming nothing else is pointing to it)?
It depends on the type of pointers. For example, smart pointers often delete their objects when they are deleted. Ordinary pointers do not. The same is true when a pointer is made to point to a different object. Some smart pointers will destroy the old object, or will destroy it if it has no more references. Ordinary pointers have no such smarts. They just hold an address and allow you to perform operations on the objects they point to by specifically doing so.
2) Following up on question 1, what defines when an object goes out of scope (not regarding to when an object leaves a given {block}). So, in other words, when is a destructor called on an object in a linked list?
That's up to the implementation of the linked list. Typical collections destroy all their contained objects when they are destroyed.
So, a linked list of pointers would typically destroy the pointers but not the objects they point to. (Which may be correct. They may be references by other pointers.) A linked list specifically designed to contain pointers, however, might delete the objects on its own destruction.
A linked list of smart pointers could automatically delete the objects when the pointers are deleted, or do so if they had no more references. It's all up to you to pick the pieces that do what you want.
3) Would you ever want to call a destructor manually?
Sure. One example would be if you want to replace an object with another object of the same type but don't want to free memory just to allocate it again. You can destroy the old object in place and construct a new one in place. (However, generally this is a bad idea.)
// pointer is destroyed because it goes out of scope,
// but not the object it pointed to. memory leak
if (1) {
Foo *myfoo = new Foo("foo");
}
// pointer is destroyed because it goes out of scope,
// object it points to is deleted. no memory leak
if(1) {
Foo *myfoo = new Foo("foo");
delete myfoo;
}
// no memory leak, object goes out of scope
if(1) {
Foo myfoo("foo");
}
Others have already addressed the other issues, so I'll just look at one point: do you ever want to manually delete an object.
The answer is yes. #DavidSchwartz gave one example, but it's a fairly unusual one. I'll give an example that's under the hood of what a lot of C++ programmers use all the time: std::vector (and std::deque, though it's not used quite as much).
As most people know, std::vector will allocate a larger block of memory when/if you add more items than its current allocation can hold. When it does this, however, it has a block of memory that's capable of holding more objects than are currently in the vector.
To manage that, what vector does under the covers is allocate raw memory via the Allocator object (which, unless you specify otherwise, means it uses ::operator new). Then, when you use (for example) push_back to add an item to the vector, internally the vector uses a placement new to create an item in the (previously) unused part of its memory space.
Now, what happens when/if you erase an item from the vector? It can't just use delete -- that would release its entire block of memory; it needs to destroy one object in that memory without destroying any others, or releasing any of the block of memory it controls (for example, if you erase 5 items from a vector, then immediately push_back 5 more items, it's guaranteed that the vector will not reallocate memory when you do so.
To do that, the vector directly destroys the objects in the memory by explicitly calling the destructor, not by using delete.
If, perchance, somebody else were to write a container using contiguous storage roughly like a vector does (or some variant of that, like std::deque really does), you'd almost certainly want to use the same technique.
Just for example, let's consider how you might write code for a circular ring-buffer.
#ifndef CBUFFER_H_INC
#define CBUFFER_H_INC
template <class T>
class circular_buffer {
T *data;
unsigned read_pos;
unsigned write_pos;
unsigned in_use;
const unsigned capacity;
public:
circular_buffer(unsigned size) :
data((T *)operator new(size * sizeof(T))),
read_pos(0),
write_pos(0),
in_use(0),
capacity(size)
{}
void push(T const &t) {
// ensure there's room in buffer:
if (in_use == capacity)
pop();
// construct copy of object in-place into buffer
new(&data[write_pos++]) T(t);
// keep pointer in bounds.
write_pos %= capacity;
++in_use;
}
// return oldest object in queue:
T front() {
return data[read_pos];
}
// remove oldest object from queue:
void pop() {
// destroy the object:
data[read_pos++].~T();
// keep pointer in bounds.
read_pos %= capacity;
--in_use;
}
~circular_buffer() {
// first destroy any content
while (in_use != 0)
pop();
// then release the buffer.
operator delete(data);
}
};
#endif
Unlike the standard containers, this uses operator new and operator delete directly. For real use, you probably do want to use an allocator class, but for the moment it would do more to distract than contribute (IMO, anyway).
When you create an object with new, you are responsible for calling delete. When you create an object with make_shared, the resulting shared_ptr is responsible for keeping count and calling delete when the use count goes to zero.
Going out of scope does mean leaving a block. This is when the destructor is called, assuming that the object was not allocated with new (i.e. it is a stack object).
About the only time when you need to call a destructor explicitly is when you allocate the object with a placement new.
1) Objects are not created 'via pointers'. There is a pointer that is assigned to any object you 'new'. Assuming this is what you mean, if you call 'delete' on the pointer, it will actually delete (and call the destructor on) the object the pointer dereferences. If you assign the pointer to another object there will be a memory leak; nothing in C++ will collect your garbage for you.
2) These are two separate questions. A variable goes out of scope when the stack frame it's declared in is popped off the stack. Usually this is when you leave a block. Objects in a heap never go out of scope, though their pointers on the stack may. Nothing in particular guarantees that a destructor of an object in a linked list will be called.
3) Not really. There may be Deep Magic that would suggest otherwise, but typically you want to match up your 'new' keywords with your 'delete' keywords, and put everything in your destructor necessary to make sure it properly cleans itself up. If you don't do this, be sure to comment the destructor with specific instructions to anyone using the class on how they should clean up that object's resources manually.
Pointers -- Regular pointers don't support RAII. Without an explicit delete, there will be garbage. Fortunately C++ has auto pointers that handle this for you!
Scope -- Think of when a variable becomes invisible to your program. Usually this is at the end of {block}, as you point out.
Manual destruction -- Never attempt this. Just let scope and RAII do the magic for you.
To give a detailed answer to question 3: yes, there are (rare) occasions when you might call the destructor explicitly, in particular as the counterpart to a placement new, as dasblinkenlight observes.
To give a concrete example of this:
#include <iostream>
#include <new>
struct Foo
{
Foo(int i_) : i(i_) {}
int i;
};
int main()
{
// Allocate a chunk of memory large enough to hold 5 Foo objects.
int n = 5;
char *chunk = static_cast<char*>(::operator new(sizeof(Foo) * n));
// Use placement new to construct Foo instances at the right places in the chunk.
for(int i=0; i<n; ++i)
{
new (chunk + i*sizeof(Foo)) Foo(i);
}
// Output the contents of each Foo instance and use an explicit destructor call to destroy it.
for(int i=0; i<n; ++i)
{
Foo *foo = reinterpret_cast<Foo*>(chunk + i*sizeof(Foo));
std::cout << foo->i << '\n';
foo->~Foo();
}
// Deallocate the original chunk of memory.
::operator delete(chunk);
return 0;
}
The purpose of this kind of thing is to decouple memory allocation from object construction.
Remember that Constructor of an object is called immediately after the memory is allocated for that object and whereas the destructor is called just before deallocating the memory of that object.
Whenever you use "new", that is, attach an address to a pointer, or to say, you claim space on the heap, you need to "delete" it.
1.yes, when you delete something, the destructor is called.
2.When the destructor of the linked list is called, it's objects' destructor is called. But if they are pointers, you need to delete them manually.
3.when the space is claimed by "new".
Yes, a destructor (a.k.a. dtor) is called when an object goes out of scope if it is on the stack or when you call delete on a pointer to an object.
If the pointer is deleted via delete then the dtor will be called. If you reassign the pointer without calling delete first, you will get a memory leak because the object still exists in memory somewhere. In the latter instance, the dtor is not called.
A good linked list implementation will call the dtor of all objects in the list when the list is being destroyed (because you either called some method to destory it or it went out of scope itself). This is implementation dependent.
I doubt it, but I wouldn't be surprised if there is some odd circumstance out there.
If the object is created not via a pointer(for example,A a1 = A();),the destructor is called when the object is destructed, always when the function where the object lies is finished.for example:
void func()
{
...
A a1 = A();
...
}//finish
the destructor is called when code is execused to line "finish".
If the object is created via a pointer(for example,A * a2 = new A();),the destructor is called when the pointer is deleted(delete a2;).If the point is not deleted by user explictly or given a new address before deleting it, the memory leak is occured. That is a bug.
In a linked list, if we use std::list<>, we needn't care about the desctructor or memory leak because std::list<> has finished all of these for us. In a linked list written by ourselves, we should write the desctructor and delete the pointer explictly.Otherwise, it will cause memory leak.
We rarely call a destructor manually. It is a function providing for the system.
Sorry for my poor English!