How to avoid Memory Leakage? (C/C++)
hiho@ll
is there a 100% way to avoid such leaks? if yes, how does it work? any hints would be great if not, how does the "not 100%" method work? i know there are some methods to avoid this (reference counting, ...), so how they work with C/C++? i could do a self-written malloc or free but the most time i use "new Object()" and STL stuff like vector or string which doesnt really make it necessary to do a malloc by my own 1: any hints (not only some doc, but some code too) would be cool 2: my biggest problem will be, what if my project i'm currently working on, is getting released and some time later strange behaviour is reported (e.g. it needs much memory resource) and i don't know why? anybody has an idea of "logging" so i can check, "ok, the most allocated object is xyz which has been allocated n times" (i would only need a hint where the leak could be) 3: i know dlopen and now i want to know if such function is available instead of the "new" keyword like this: void* instantiateObject(char *classname,...); /*... is an argument list for the constructor like a list for printf();*/ thx@ll |
i guess one "tip" would be to make sure your write destructor for any classes you write that allocate memory in the constructor.
|
What works 100% is manually and correctly freeing allocated memory.
What also works is reference counting, if your object structures don't contain cycles. If they do contain cycles, try to break them up, make some references weak, or encapsulate the cycle in some class and break in the destructor of that class. shared_ptr from the boost library does the reference counting for you. You may also want to override operator new and count each allocation (and possibly override operator delete--similarly for the array-operators--to see if any object is leaked). Alternatively, put the allocation counting in an allocator class. hth --Jonas |
this is what i use to track any leaks, but there seems to be a problem with including it in header files and only seems to work if include in the .cpp file. dont know why?
anyway I'm some peeps are going to say theres something wrong with this lol. also it checks if malloc failed, but doesnt do anything about it! example of how i use it. main.cpp Code:
#include <memory_check.h> Code:
#define _MEMORY_CHECK_H_ i should add that i use this code to test parts of code and not full apps. |
First, a 100% way of preventing memory leak would be equivalent to the halting problem. (ie. Provably impossible)
Secondly the best design principle is to consider carefully who sould own and be responsible for the allocation and deallocation of the data. The Law of Demeter can be a guide in deciding this, so can the notion of object lifetimes. (ie. The owner must live as least as long as any user of the data) Thirdly, most practically, use valgrind. It is very very good. |
the idea with overriding operators seems good
but i think i'll have a look @ http://www.hpl.hp.com/personal/Hans_Boehm/gc/ @dmail thx for your code i think i'll use some parts for the beginning thx@ll |
not sure about %100 But,
1.try not to use memory allocation as possible. 2. ask gnome developer who digging 2.14 as you know, that's why .net and java born. pragmatic programmer http://www.amazon.com/exec/obidos/tg...1622X?v=glance |
Quote:
valgrind can usually be downloaded with your gcc/g++ compiler packages. For example, in Ubuntu, you'd just: apt-get install valgrind It's a great tool, specifically for finding memory leaks. |
I'm not sure exactly what you are after. You said some documentation or some code would be cool.
I have here some code for automatic reference counting in c++, that works for objects that inherit the Object class, it is far from complete, but it makes a good example. Just remember when you are using reference counting and you have a child class referencing a perent class and that parent class referencing that same child class, make the child class using a weak reference (just a pointer), that way memory leaks will not occur from circular dependancies. Code:
////////////////////////////////////////////////////////////////////////////// Code:
////////////////////////////////////////////////////////////////////////////// Code:
class A: virtual public Object { |
See my next post for an example of what can go wrong with ref counted pointers.
|
See my previous post for an example of what can go wrong with ref counted pointers.
|
cyent has a point in his/her last two posts, this problem is mainly avoided by using weak references.
class PhysicsSystem { public: . . . BLAH BLAH BLAH . . . private: list<Ref<PhysicsObject> > mPhysicsObjects; }; class PhysicsObject { public: . . . BLAH BLAH BLAH . . . private: PhysicsSystem* mpParent; }; In the two examples any of the mPhysicsObjects are referenced to a PhysicsObject, where as each of the PhysicsObject's mpParent(s) are weakly referenced back to the PhysicsSystem it belongs too. The type PhysicsSystem* is a weak reference, because it is a pointer without any reference counting. The type Ref<PhysicsObject> is a actual reference, that will do reference counting, and hits zero and deletes itself once nobody is using the PhysicsObject that it references anymore. Sometimes a system can be too complex to correctly implement with a combination of References and Weak References, in which case Garbarge Collection is a ok idea. Garbages Collection is faster than reference counting, because it does not have to update a counter, and because it does not have to free any memory until any criterion to Collect the Garbage has been meet. Most the time reference counting should be ok, but do not over use it. Only use it in areas which it is helpful, do not use it for everything. If you have an instance of an object that is only used by one piece of code (like a single class), then do not use reference couning. But if you have an object that a heap of classes may contain, and the order of destruction of the classes is not predetermined or can happen in any order, then do use reference counting. When using reference counting be carefull to make sure there are no circular dependances, and eleminate any circular dependances with a weak reference. E.g. a doubling linked list with references for the nodes (maybe because the nodes can be spliced together in a specialised list, mimicing a tree), then make the nodes have a Reference to the next node and just a Weak reference to the previous node. Then when you are done unreference the first node and what them all blow up like a chain reaction, until you list is freed. Unfortunatly if you were implementing a circular list you would have a circular dependance still event with the implementation described in the previos paragraph. And in this case you might now want to use Reference Counting or just simply have a flag at the end of the list where the tail joins to the front so you can double unreference. |
If you need a pointer to an object that will automatically free itself, and is only needed by one section or piece of code, then you can use Auto Pointers.
Code:
template <class T> One problem is that if you wanted more that the one copy of this object, you would have to make more exact copies instead of using the same one. AutoPtr<Crap>* pMyCrap = new Crap; AutoPtr<Crap>* pACopyOfMyCrap = new Crap(*pMyCrap); So on the down side it uses more memory, but on the up side no memory leaks. Sometimes this can be just as bad as stack variables, and your just better of using them. AutoPtr(s) are good when you do not have the information to create the object until a function is called that supplies the information. Sort of like delayed construction. Like a render function for a 3d model might supply the plugin for the video at render time, but not at the loading time of the 3d model, so the loading of the textures can be delayed until the video plugin can allocate a texture from video memory to give to the 3d model to use for rendering, then in the next render the texture is no longer needed to be allocated. |
that's a hard topic
i had to read it twice to understand ;-) but how does garbace collection work? are AutoPtr the only way in C++? i mean i understand how php or java garbace collection may work those languages are interpreted so it's more or less easy but in C/C++ it seems a challenge to do it correctly |
AutoPtrs are not the only way!!!
Garbage collection works too, but it is a fair amount of work. It involves creating a seperate thread on low priority to check the memory once in a while, and you also must overload your new, new[], delete, delete[] operators, and your malloc() and free() functions, if you entend to use them as well. To create the platform independand thread for the garbage collection you can use SDL_Thread from the SDL library. When memory is allocated, extra space for a void* should be allocated as well, so that all allocated objects can be linked together in a forward singular link list fasion. Also you should store the location of the head and the tail of the list as static void pointers in the source file for garbage collection. When new memory is allocated it must be linked on the tail, and when the garbage is collected all the memory should be freed following from the head node onwards. Also add a dummy class with a dummy static object in your garbage collection source to make sure the all the garbage is collected, so that the garbage is collected before your application terminates. Code:
class _ { |
All times are GMT -5. The time now is 07:45 PM. |