Reputation: 1033
Running valgrind or purify would be the next steps But while while writing the code itself how do you ensure that it will not cause any memory leaks? You can ensure following things:- 1: Number of new equal to delete 2: Opened File descriptor is closed or not
Is there any thing else?
Upvotes: 6
Views: 594
Reputation: 51709
On 1) RAII, the idea is to have deletes happen automatically, if you find yourself thinking "I just called new, I'll need to remember to call delete somewhere" then you're doing something wrong. The delete should either be a) automatic or b) be put in a dtor (and which dtor should be obvious).
On 2) Hiding defaults. Identifying rogue default copy ctors etc can be a nightmare, the easiest thing is to avoid them by hiding them. If you have a generic "root" object that everything inherits from (can be handy for debugging / profiling anyway) hide the defaults here, then when an something tries to assign / copy an inheriting class the compiler barfs because the ctor's etc aren't available on the base class.
Upvotes: 5
Reputation:
Avoid creating objects dynamically wherever possible. Programmers coming from Java and other similar languages often write stuff like:
string * s = new string( "hello world" );
when they should have written:
string s = "hello world";
Similarly, they create collections of pointers when they should create collections of values. For example, if you have a class like this:
class Person {
public:
Person( const string & name ) : mName( name ) {}
...
private:
string mName;
};
Rather than writing code like:
vector <Person *> vp;
or even:
vector <shared_ptr <Person> > vp;
instead use values:
vector <Person> vp;
You can easily add to such a vector:
vp.push_back( Person( "neil butterworth" ) );
and all the memory for both Person and the vector is managed for you. Of course, if you need a collection of polymorphic types, you should use (smart) pointers
Upvotes: 14
Reputation: 1398
Incorporate valgrind unit and system testing early in your development cycle and use it consistantly.
Upvotes: 0
Reputation: 24902
I'm with Glen and jalf regarding RAII at every opportunity.
IMHO you should aim to write completely delete-free code. The only explicit "delete"s should be in your smart pointer class implementations. If you find yourself wanting to write a "delete", go and find an appropriate smart pointer type instead. If none of the "industry standard" ones (boost's etc) fit and you find yourself wanting to write some bizzare new one, chances are your architecture is broken or at the least there will be maintenance difficulties in future.
I've long held that explicit "delete" is to memory management what "goto" is to flow control. More on this in this answer.
Upvotes: 3
Reputation: 247899
Two simple rules of thumb:
delete
explicitly (outside a RAII class, that is). Every memory allocation should be the responsibility of a RAII class which calls delete in the destructor.new
explicitly. If you do, you should immediately wrap the resulting pointer in a smart pointer, which takes ownership of the allocation, and works as above.In your own RAII classes, two common pitfalls are:
std::vector
has to handle this, during push_back
for example. It might cause the vector to resize, which means 1) a memory allocation which may throw, and 2) all the existing elements have to be copied, each of which may throw. An algorithm like std::sort
has to deal with it too. It has to call a user-supplied comparer, which could potentially throw too! if that happens, is the sequence left in a valid state? Are temporary objects destructed cleanly?If you handle the above two cases in your RAII classes, it is pretty much impossible for them to leak memory. And if you use RAII classes to wrap all resource allocations (memory allocations, file handles, database connections and any other type of resource that has to be acquired and released), then your application can not leak memory.
Upvotes: 1
Reputation: 52659
The basic steps are twofold:
Firstly, be aware that every new requires a delete. So, when you use the new operator, up your awareness of what that object will be doing, how it will be used, and how its lifetime will be managed.
Secondly, make sure that you never overwrite a pointer. You can do this using a smart pointer class instead of raw pointers, but if you do make absolutely sure you never use it with implicit conversion. (an example: using MSXML library, I created a CCOMPtr smart pointer to hold nodes, to get a node you call the get_Node method, passing in the address of the smart pointer - which had a conversion operator that returned the underlying pointer type. Unfortunately, this meant that if the smart pointer already held data, that member data would be overwritten, leaking the previous node).
I think those 2 cases are the times when you might leak memory. If you only use the smart pointer directly - never allowing its internal data to be exposed, you're safe from the latter issue. If you wrap all your code that uses new and delete in a class (ie using RAII) then you're pretty safe from the former too.
Avoiding memory leaks in C++ is very easy if you do the above.
Upvotes: 1
Reputation: 19325
Minimize the calls to new by using the STL containers for storing your data.
Upvotes: 4
Reputation: 12027
There are static code analysis tools available that do this sort of thing; wikipedia is a good place to start looking. Basically, outside of being careful and choosing the correct containers you can not make guarantees about the code you write - hence the need for tools such as valgrind and gdb.
Upvotes: 0
Reputation: 7411
if you make any tree or graph recursively in your code for your data structure maybe eat all of your memory.
Upvotes: 0
Reputation: 924
I always use std::auto_ptr
when I need to create a new object on the heap.
std::auto_ptr<Foo> CreateFoo()
{
return std::auto_ptr<Foo>(new Foo());
}
Even if you call
CreateFoo()
it won't leak
Upvotes: 1
Reputation: 10660
Make sure shared memory created by your application is freed if nobody's using it anymore, clean up memory mapped files...
Basically, make sure you clean up any type of resource your application directly or indirectly creates. File descriptors are only one type of resource your application may use during runtime.
Upvotes: 0