Here is a sample code that I have:
void test()
{
Object1 *obj = new Object1();
.
.
.
delete obj;
}
I run it in Visual Studio, and it crashes at the line with 'delete obj;'.
Isn't this the normal way to free the memory associated with an object?
I realized that it automatically invokes the destructor... is this normal?
Here is a code snippet:
if(node->isleaf())
{
vector<string> vec = node->L;
vec.push_back(node->code);
sort(vec.begin(), vec.end());
Mesh* msh = loadLeaves(vec, node->code);
Simplification smp(msh);
smp.simplifyErrorBased(errorThreshold);
int meshFaceCount = msh->faces.size();
saveLeaves(vec, msh);
delete msh;
}
loadleaves() is a function that reads a mesh from disk and creates a Mesh object and returns it.(think of vec and node->code are just information about the file to be opened)
Should I remove the delete msh; line?
Isn't this the normal way to free the memory associated with an object?
This is a common way of managing dynamically allocated memory, but it's not a good way to do so. This sort of code is brittle because it is not exception-safe: if an exception is thrown between when you create the object and when you delete it, you will leak that object.
It is far better to use a smart pointer container, which you can use to get scope-bound resource management (it's more commonly called resource acquisition is initialization, or RAII).
As an example of automatic resource management:
void test()
{
std::auto_ptr<Object1> obj1(new Object1);
} // The object is automatically deleted when the scope ends.
Depending on your use case, auto_ptr might not provide the semantics you need. In that case, you can consider using shared_ptr.
As for why your program crashes when you delete the object, you have not given sufficient code for anyone to be able to answer that question with any certainty.
Your code is indeed using the normal way to create and delete a dynamic object. Yes, it's perfectly normal (and indeed guaranteed by the language standard!) that delete will call the object's destructor, just like new has to invoke the constructor.
If you weren't instantiating Object1 directly but some subclass thereof, I'd remind you that any class intended to be inherited from must have a virtual destructor (so that the correct subclass's destructor can be invoked in cases analogous to this one) -- but if your sample code is indeed representative of your actual code, this cannot be your current problem -- must be something else, maybe in the destructor code you're not showing us, or some heap-corruption in the code you're not showing within that function or the ones it calls...?
BTW, if you're always going to delete the object just before you exit the function which instantiates it, there's no point in making that object dynamic -- just declare it as a local (storage class auto, as is the default) variable of said function!
Isn't this the normal way to free the memory associated with an object?
Yes, it is.
I realized that it automatically invokes the destructor... is this normal?
Yes
Make sure that you did not double delete your object.
if it crashes on the delete line then you have almost certainly somehow corrupted the heap. We would need to see more code to diagnose the problem since the example you presented has no errors.
Perhaps you have a buffer overflow on the heap which corrupted the heap structures or even something as simple as a "double free" (or in the c++ case "double delete").
Also, as The Fuzz noted, you may have an error in your destructor as well.
And yes, it is completely normal and expected for delete to invoke the destructor, that is in fact one of its two purposes (call destructor then free memory).
saveLeaves(vec,msh); I'm assuming takes the msh pointer and puts it inside of vec. Since msh is just a pointer to the memory, if you delete it, it will also get deleted inside of the vector.
Just an update of James' answer.
Isn't this the normal way to free the memory associated with an object?
Yes. It is the normal way to free memory. But new/delete operator always leads to memory leak problem.
Since c++17 already removed auto_ptr auto_ptr. I suggest shared_ptr or unique_ptr to handle the memory problems.
void test()
{
std::shared_ptr<Object1> obj1(new Object1);
} // The object is automatically deleted when the scope ends or reference counting reduces to 0.
The reason for removing auto_ptr is that auto_ptr is not stable in case of coping semantics
If you are sure about no coping happening during the scope, a unique_ptr is suggested.
If there is a circular reference between the pointers, I suggest having a look at weak_ptr.
Related
This seems like a rather trivial or at least common question, but I couldn't find a satisfying answer on google or on SO.
I'm not sure when I should implement a destructor for my class.
An obvious case is when the class wraps a connection to a file, and I want to make sure the connection is closed so I close it in the destructor.
But I want to know in general, how can I know if I should define a destructor. What guidelines are there that I can check to see if I should have a destructor in this class?
One such guideline I can think of, is if the class contains any member pointers. The default destructor would destory the pointers on deletion, but not the objects they're pointing at. So that should be the work of a user-defined destructor. E.g: (I'm a C++ newbie, so this code might not compile).
class MyContainer {
public:
MyContainer(int size) : data(new int[size]) { }
~MyContainer(){
delete [] data;
}
// .. stuff omitted
private:
int* data;
}
If I hadn't supplied that destructor, than destroying a MyContainer object would mean creating a leak, since all the data previously referenced by data wouldn't have been deleted.
But I have two questions:
1- Is this the only 'guideline'? I.e. define a destructor if the class has member pointers or if it's managing a resource? Or is there anything else?
2- Are there cases when I should not delete member pointers? What about references?
You need to define a destructor if the default destruction does not suffice. Of course, this just punts the question: what does the default destructor do? Well, it calls the destructors of each of the member variables, and that's it. If this is enough for you, you're good to go. If it's not, then you need to write a destructor.
The most common example is the case of allocating a pointer with new. A pointer (to any type) is a primitive, and the destructor just makes the pointer itself go away, without touching the pointed to memory. So the default destructor of a pointer does not have the right behavior for us (it will leak memory), hence we need a delete call in the destructor. Imagine now we change the raw pointer to a smart pointer. When the smart pointer is destroyed, it also calls the destructor of whatever its pointing to, and then frees the memory. So a smart pointer's destructor is sufficient.
By understanding the underlying reason behind the most common case, you can reason about less common cases. It's true that very often, if you're using smart pointers and std library containers, their destructors do the right thing and you don't need to write a destructor at all. But there are still exceptions.
Suppose you have a Logger class. This logger class is smart though, it buffers up a bunch of messages to Log, and then writes them out to a file only when the buffer reaches a certain size (it "flushes" the buffer). This can be more performant than just dumping everything to a file immediately. When the Logger is destroyed, you need to flush everything from the buffer regardless of whether it's full, so you'll probably want to write a destructor for it, even though its easy enough to implement Logger in terms of std::vector and std::string so that nothing leaks when its destroyed.
Edit: I didn't see question 2. The answer to question 2 is that you should not call delete if it is a non-owning pointer. In other words, if some other class or scope is solely responsible for cleaning up after this object, and you have the pointer "just to look", then do not call delete. The reason why is if you call delete and somebody else owns it, the pointer gets delete called on it twice:
struct A {
A(SomeObj * obj) : m_obj(obj){};
SomeObj * m_obj;
~A(){delete m_obj;};
}
SomeObj * obj = new SomeObj();
A a(obj);
delete obj; // bad!
In fact, arguably the guideline in c++11 is to NEVER call delete on a pointer. Why? Well, if you call delete on a pointer, it means you own it. And if you own it, there's no reason not to use a smart pointer, in particular unique_ptr is virtually the same speed and does this automatically, and is far more likely to be thread safe.
Further, furthermore (forgive me I'm getting really into this now), it's generally a bad idea to make non-owning views of objects (raw pointers or references) members of other objects. Why? Because, the object with the raw pointer may not have to worry about destroying the other object since it doesn't own it, but it has no way of knowing when it will be destroyed. The pointed to object could be destroyed while the object with the pointer is still alive:
struct A {
SomeObj * m_obj;
void func(){m_obj->doStuff();};
}
A a;
if(blah) {
SomeObj b;
a.m_obj = &b;
}
a.func() // bad!
Note that this only applies to member fields of objects. Passing a view of an object into a function (member or not) is safe, because the function is called in the enclosing scope of the object itself, so this is not an issue.
The harsh conclusion of all this is that unless you know what you're doing, you just shouldn't ever have raw pointers or references as member fields of objects.
Edit 2: I guess the overall conclusion (which is really nice!) is that in general, your classes should be written in such a way that they don't need destructors unless the destructors do something semantically meaningful. In my Logger example, the Logger has to be flushed, something important has to happen before destruction. You should not write (generally) classes that need to do trivial clean-up after their members, member variables should clean up after themselves.
A class needs a destructor when it "owns" a resource and is responsible for cleaning it up. The purpose of the destructor is not simply to make the class itself work properly, but to make the program as a whole work properly: If a resource needs to be cleaned up, something needs to do it, and so some object should take responsibility for the cleanup.
For instance, memory might need to be freed. A file handle might need to be closed. A network socket might need to be shut down. A graphics device might need to be released. These things will stay around if not explicitly destroyed, and so something needs to destroy them.
The purpose of a destructor is to tie a resource's lifetime to an object's, so that the resource goes away when the object goes away.
A Destructor is useful for when your classes contain Dynamically Allocated Memory. If your classes are simple and don't have 'DAM', then it's safe to not use a Destructor. In addition, read about the Rule Of Three. You should also add a copy constructor and an overloaded = operator if your class is going to have 'DAM'.
2) Do not worry about References. They work in a different way such as that it "Refers" to another variable (Which means they don't point to the memory).
Let say you have a class like this
class Level
{
public:
Level(std::string);
~Level();
private:
Bitmap* map;
}
and in the class you had this
Level::Level(std::string)
{
map = new Bitmap(path);
}
Was wondering do can you call
Level::~Level()
{
delete map;
}
As I was worried about if the class goes out of scope and I haven't deleted map. Then, wouldn't that cause a memory leak. Do I have to manually call to delete map. As I get crash if I call delete in the constructor in my program.
Like I could add a method to Level called say destroy map where I delete map. But, was wondering why I can't add delete into the destructor.
When the Level object goes out of scope, its destructor will be called, so deallocation of memory is useful because that memory is no longer needed. You can also use a unique_ptr, whereby memory-deallocation performed automatically.
This is why destructors stand for. Destructor is explicitly called when your object goes out of scope (memory residing on the stack objects) or when delete is called ( for dynamically allocated objects), so that the memory the object kept would be released. If you want to release member objects memory when destroyed, you can call the destructors of each object using delete (or delete[] for arrays). It is better that you use smart pointers, to avoid unintentional memory leaks and to ensure the memory is freed correctly in all cases, as they use RAII concept (RAII and smart pointers in C++).
Answers already have pointed out that you can trust your destructor to be called when your object goes out of scope. I won't reiterate that. I just wanted to point out that there is no need to allocate your Bitmap with new (unless you were using custom memory allocators, which is not the case here). You can construct it with an initialiser list:
class Level
{
public:
Level(std::string);
private:
Bitmap map;
};
Level::Level(std::string)
: map(path)
{
}
Now it has automatic scope and you don't have to worry about your destructor.
That's basically right.
However:
You need to make sure you create a copy constructor and assignment operator too, if you are managing memory this way. (That's where your crash comes from.)
An alternative, the best way, is to use RAII and store not a raw pointer but a scoped or automatic pointer. Or even just a directly encapsulated object! Then you don't need the delete at all.
As I was worried about if the class goes out of scope and I haven't deleted map. Then, wouldn't that cause a memory leak.
You're right - you should delete map exactly as your code does. But, you should also make your object non-copyable (derive from boost or C++11 noncopyable base classes, or add a private declaration (with no definition/implementation) of the operator= copy assignment and copy constructor. Otherwise, if you (deliberately or accidentally or incidentally - e.g. when storing your object in a container that sometimes copies it around, such as a std::vector) copy your object, then the first copy destructored will delete the map, any other copy that tries to use it will likely crash, and any other copy's destructor that also tries to delete it will also have undefined behaviour.
Do I have to manually call to delete map.
Yes, in your code you do.
A better alternative is to use a smart pointer whose own destructor will delete the pointed-to object.
As I get crash if I call delete in the constructor in my program.
Well, if you call delete after the new, then the constructor won't crash, but you wouldn't have a map object to use after the constructor returns, and if you then try to delete it again in the destructor the you get undefined behaviour which may well manifest as a crash.
If you want to delete the map earlier than the destructor sometimes, you can set the pointer to NULL so that a future delete will do nothing safely. You should then check for NULL before trying to use the map.
Like I could add a method to Level called say destroy map where I delete map. But, was wondering why I can't add delete into the destructor.
As above, you can have destroy_map, but it must coordinate with the destructor.
When there's no compelling reason to do otherwise, it's better to make the map member data, not storing it by reference. When a pointer is useful, use a smart pointer if at all possible. If you want to implement explicit manual memory management, be wary of the issues above.
This is an unusual way to do it. Normally, an object's lifetime is determined by factors outside of the object.
But in fact MFC used to (still does?) do exactly this when a Window is being destroyed. (In response to WM_NCDESTROY, I believe.) This ensures you don't have the Window instances leaking memory after the window is gone.
So I would say it is valid in some cases. You might call it class suicide!
I am writing a class (virtual_flight_runtime_environment), and it is mostly non-static, with the exception of one static function for the purposes of a Win32 thread using it as its function. The class declares struct simaircraftdata* aircraftdata (a data struct), and calls 'aircraftdata = new aircraftdata;' in the constuctor (public: virtual_flight_runtime_environment()).
My question is about destructors and memory deallocation. I have written the destructor as such:
~virtual_flight_runtime_environment(void) {
/*..Other code, i.e. closing win32 handles, etc.*/
delete aircraftdata;
}
Now, the class is declared in another function (the DoWork function of a .Net background worker) like so:
virtual_flight_runtime_environment* this_environment = new virtual_flight_runtime_environment;
And just before the end of the function, I call 'delete this_environment;'. Immediately after, 'this_environment' would have gone out of scope, and the desturctor should have been called.
Is this correct? I do notice continued increases in memory usage over time, and I'm wondering if I've done something wrong. Does calling delete on a pointer just make it a null pointer, or does it deallocate the data at the end of it?
Any advice would be appreciated,
Collin Biedenkapp
There is no direct connection between a delete in your program and whether it will directly be visible in say the task manager because the OS tries to optimize memory utilization. When you look in the task manager you will typically see the working set size of your application, this is a measure of how much memory your app has requested but not necessarily how much it is currently using.
And to your question, yes deleting the memory as you did it is the WTG although as others have pointed out using smart pointers is generally much better to handle memory to avoid later headaches.
You're almost correct.
delete this_environment calls the destructor of virtual_flight_runtime_environment. The destructor executes delete aircraftdata.
Right after that, the memory occupied by the instance of virtual_flight_runtime_environment is released.
Please be aware that delete statement doesn't set the pointer to NULL.
So I see no problem in your code given the information in the question.
This looks correct.
Calling delete on your this_environment will cause the destructor of that class to be called before it's memory is deallocated. The destructor deletes the aircraft data. Looks correct.
You might consider instead of having a member variable containing a raw pointer to aircraftdata instead using an auto_ptr or in c++11 unique_ptr which will ensure that it gets deleted automatically when it's containing class is constructed. Look it up, this isn't the place to teach it and it's just a suggestion, not a necessity.
Edit: And I also agree with Pete Becker's comment on the question, which is to question if this needs a pointer at all.
You should indeed explicitely call "delete this_environment". Otherwise, it's only the pointer itself (which exists on the stack) which would be destroyed. The data pointed, on the heap, would still exist.
The other solution is to simply get rid of the pointer and declare your variable as such :
virtual_flight_runtime_environment this_environment;
That way, your object will directly exist on the stack, and its lifetime will depend on the scope in which it is declared - and the destructor will be automatically called at this point, calling in turn the delete for your internal data.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Is it safe to delete this?
I've been doing a little work on a class that's designed to act as a node in a linked list, and I figured I'd give the class its own deletion function as opposed to the managing class doing it. So basically it goes like this:
void Class::Delete() {
//Some cleanup code before deleting the object
delete this;
}
Now I've tested this and it appears to work fine, but I've had a problem in the past where objects have been in the middle of running code, been deleted, then obviously crashed the program by trying to use a no-longer-existing object.
Since "delete this" is right at the end of the function, it obviously exits the function and works fine, but is this sort of practice a bad idea at all? Could this ever blow up in my face if I'm not careful?
The FAQlite answers this quite well:
As long as you're careful, it's OK for
an object to commit suicide (delete
this).
Here's how I define "careful":
You must be absolutely 100% positive sure that this object was
allocated via new (not by new[], nor
by placement new, nor a local object
on the stack, nor a global, nor a
member of another object; but by plain
ordinary new).
You must be absolutely 100% positive sure that your member
function will be the last member
function invoked on this object.
You must be absolutely 100% positive sure that the rest of your
member function (after the delete this
line) doesn't touch any piece of this
object (including calling any other
member functions or touching any data
members).
You must be absolutely 100% positive sure that no one even touches
the this pointer itself after the
delete this line. In other words, you
must not examine it, compare it with
another pointer, compare it with NULL,
print it, cast it, do anything with
it.
Naturally the usual caveats apply in
cases where your this pointer is a
pointer to a base class when you don't
have a virtual destructor.
Basically, you need to take the same care as you do with deleteing any other pointer. However, there are more areas where things can go wrong with a member function committing suicide, compared with an explicitly-declared pointer.
Using delete this is a bad idea if one is not sure of the pitfalls & working around them.
Once you call delete this the object's destructor is going to be invoked and the dynamically allocated memory will be freed.
If the object was not allocated using new, it will be a Undefined behaviour.
If any of object's data members or virtual functions are accessed after delete this, the behaviour will be Undefined Behavior again.
Probably, It is best to avoid delete this given the above.
It's actually a frequent idiom, and about as safe as any delete. As
with all deletes, you have to ensure that no further code tries to
access the object, and you have to be sure that the object was
dynamically allocated. Typically, however, the latter is not a
problem, since the idiom is only relevant for objects which have a
lifetime determined by the semantics of the object, and such objects are
always allocated dynamically. Finding all of the pointers too the
object can be an issue (whether delete this is used or not); usually,
some form of the observer pattern will be used to notify all interested
parties that the object will cease to exist.
The idiomatic way of doing that in C++ is by putting the cleanup code in the destructor then let it be called automatically when you delete the object.
Class::~Class() {
do_cleanup();
}
void ManagingClass::deleteNode(Class* instance) {
delete instance; //here the destructor gets called and memory gets freed
}
There's a simple way of doing the same thing that doesn't involve undefined behavior:
void Class::Delete() {
//Some cleanup code before deleting the object
std::auto_ptr delete_me(this);
}
While learning different languages, I've often seen objects allocated on the fly, most often in Java and C#, like this:
functionCall(new className(initializers));
I understand that this is perfectly legal in memory-managed languages, but can this technique be used in C++ without causing a memory leak?
Your code is valid (assuming functionCall() actually guarantees that the pointer gets deleted), but it's fragile and will make alarm bells go off in the heads of most C++ programmers.
There are multiple problems with your code:
First and foremost, who owns the pointer? Who is responsible for freeing it? The calling code can't do it, because you don't store the pointer. That means the called function must do it, but that's not clear to someone looking at that function. Similarly, if I call the code from somewhere else, I certainly don't expect the function to call delete on the pointer I passed to it!
If we make your example slightly more complex, it can leak memory, even if the called function calls delete. Say it looks like this: functionCall(new className(initializers), new className(initializers)); Imagine that the first one is allocated successfully, but the second one throws an exception (maybe it's out of memory, or maybe the class constructor threw an exception). functionCall never gets called then, and can't free the memory.
The simple (but still messy) solution is to allocate memory first, and store the pointer, and then free it in the same scope as it was declared (so the calling function owns the memory):
className* p = new className(initializers);
functionCall(p);
delete p;
But this is still a mess. What if functionCall throws an exception? Then p won't be deleted. Unless we add a try/catch around the whole thing, but sheesh, that's messy.
What if the function gets a bit more complex, and may return after functionCall but before delete? Whoops, memory leak. Impossible to maintain. Bad code.
So one of the nice solutions is to use a smart pointer:
boost::shared_ptr<className> p = boost::shared_ptr<className>(new className(initializers));
functionCall(p);
Now ownership of the memory is dealt with. The shared_ptr owns the memory, and guarantees that it'll get freed. We could use std::auto_ptr instead, of course, but shared_ptr implements the semantics you'd usually expect.
Note that I still allocated the memory on a separate line, because the problem with making multiple allocations on the same line as you make the function call still exists. One of them may still throw, and then you've leaked memory.
Smart pointers are generally the absolute minimum you need to handle memory management.
But often, the nice solution is to write your own RAII class.
className should be allocated on the stack, and in its constructor, make what allocations with new are necessary. And in its destructor, it should free that memory. This way, you're guaranteed that no memory leaks will occur, and you can make the function call as simple as this:
functionCall(className(initializers));
The C++ standard library works like this. std::vector is one example. You'd never allocate a vector with new. You allocate it on the stack, and let it deal with its memory allocations internally.
Yes, as long as you deallocate the memory inside the function. But by no means this is a best practice for C++.
It depends.
This passes "ownership" of the memory to functionCAll(). It will either need to free the object or save the pointer so that it can be freed later. Passing the ownership of raw pointers like this is one of the easiest ways to build memory issues into your code -- either leaks or double deletes.
In C++ we would not create the memory dynamically like that.
Instead you would create a temporary stack object.
You only need to create a heap object via new if you want the lifetime of the object to be greater than the call to the function. In this case you can use new in conjunction with a smart pointer (see other answers for an example).
// No need for new or memory management just do this
functionCall(className(initializers));
// This assumes you can change the functionCall to somthing like this.
functionCall(className const& param)
{
<< Do Stuff >>
}
If you want to pass a non const reference then do it like this:
calssName tmp(initializers);
functionCall(tmp);
functionCall(className& param)
{
<< Do Stuff >>
}
It is safe if the function that you are calling has acceptance-of-ownership semantics. I don't recall a time where I needed this, so I would consider it unusual.
If the function works this way, it should take its argument as a smart pointer object so that the intent is clea; i.e.
void functionCall(std::auto_ptr<className> ptr);
rather than
void functionCall(className* ptr);
This makes the transfer of ownership explicit, and the calling function will dispose of the memory pointed to by ptr when execution of the function falls out of scope.
This will work for objects created on the stack, but not a regular pointer in C++.
An auto pointer maybe able to handle it, but I haven't messed with them enough to know.
In general, no, unless you want to leak memory. In fact, in most cases, this won't work, since the result of
new T();
in C++ is a T*, not a T (in C#, new T() returns a T).
Have a look at Smart Pointers or A garbage collector for C and C++.