Rules for dynamic memory allocation!
Rules that I follow for dynamic memory allocation are as follows…
1. Do not mix different memory allocation and freeing mechanisms. For e.g. do not use free to free memory allocated by new and do not use delete to free memory allocated by malloc/calloc etc. You may ask why, the answer is simple, it’s just not meant to work that way. The new operator invokes constructor to make sure that all nested objects in the object that’s being allocated is initialized (of course onus lies on the implementor, but still give him a chance) and delete as expected calls destructor allowing implementor to free any allocated memory during the object’s lifetime.
2. Let the allocator free! I would advise you to follow this rule religiously. What does this mean? It simply means that if you haven’t allocated a chunk of memory then don’t free it too. If there is a dll which allocates memory make sure that the dll has a corresponding free function too. Look at how COM works, we don’t have to delete the COM object it get’s deleted automatically when reference count reaches zero on last Release call by the dll which allocated the object. Now you might say that some windows API’s like CommandLineToArgvW does violate this rule, it’s bad but it’s well documented too so that should be fine. 🙂 Main reason for this being that we don’t know what kind of allocation mechanism has been used. For external users it might look like a valid pointer allocated using new but internally it could be placement new which again might be using a buffer on stack (never know right!). So let the implementors worry about how or whether to free it. We just guarantee that we will call a corresponding free function.
3. Always set a deleted pointer to NULL if it’s still in scope. delete doesn’t set a pointer to NULL after deletion.
4. new doesn’t throw exceptions these days (did it at all?) so better check for NULL after a call to new. You might be waiting for an exception which won’t just happen.
5. If possible try to wrap allocated object pointers in an auto_ptr object. This makes sure that the object get freed at all cost. The best thing about an auto_ptr object we don’t have to worry about when to free and makes code look clean instead having frees/deletes all over place. Think about a case where you have multiple return statements, phew, go and write deletes wherever there is a return and you will know what I am talking about. Instead use an auto_ptr and see the difference. These days we have shared_ptr which could be just what C++ developers wanted for a long time.
6. If possible use collection classes like STL’s std::vector / std::list / std::dqueue / std::map. Which one to use depends on what your needs are. As it is said do not rewrite TCP/IP to do network programming. Try to reuse reliable classes that has already been done for you. You might want to manage a list of employees coming in and going out your office, so use a vector or list. Another time you might want to assign names then use string allowing your application to scale and also removes length dependency on names.
7. If you are overloading operator new then override operator delete too!