When you are writing a program and you want it to be able to run for a long period of time or when some procedure is called a times in the lifetime of running program (let tend to infinity) maybe is a good opportunity to make sure all your calls have one call (, in C++).This sounds very natural to any experienced programmer.
Now imagine that you have download some huge chunk of code and you want to call it times, lets say 100 times per second. Maybe the person who wrote the code, did not think about memory management and maybe you do not have the patience to read the huge piece of code. What you need is a memory leak detector.
If you do not have any of these problems might be interested in knowing how to gain millions of euros on the internet.
Here I will show an example of how to write a simple memory leak detector in C++ for C , is trivial to convert it to verify memory leaks in C++.
The main idea is to keep the line number of each we do and then verify if we did , we will accomplish this by redefining the and call, without need to write our own or , thanks to C pre processor.
First we define an entity, this keep all the information we need about each call.
class Entity { private: unsigned int _address; unsigned int _line; public: Entity(unsigned int addr, unsigned int line) { this->_address = addr; this->_line = line; } unsigned int & getOrSetAddress() { return this->_address; } unsigned int getLine() { return this->_line; } }; typedef std::list<Entity *> Memory; Memory *memory;
I used the standard C++ lists instead of std::vector because I will need to remove and add elements, without the need to call in algorithms module, what bugs me.
Now I will define the function to add elements to our std::list
void InsertOnMalloc(unsigned int addr, unsigned int n) { if(!memory) memory = new Memory; memory->insert(memory->begin(), new Entity(addr,n)); }
Now I will define the function to remove elements to our std::list
void RemoveOnFree(unsigned int addr) { if(!memory) return; for(Memory::iterator it = memory->begin(); it != allocList->end(); it++) { Entity *entity = *it; if(entity->getOrSetAddress() == addr) { memory->remove(); break; } } }
The idea so far is to call for each call and for each . After this if we have any element in our we need to print that out, to see which line we do not call .
void ShowLeaks() { for(Memory::iterator it = memory->begin(); it != memory->end(); it++) std::cout << "Must make free to this malloc call: " << (*it)->getLine() << std::endl; }
Now, lets do the real juice of this leak detector: here I will modify the call to a regular followed by an insertion, and a call for a regular call followed by removal on our list
#define malloc(p) mallocz((p),__LINE__) #define free(p) freez((p)) static inline void * mallocz(unsigned int size, int line) { #undef malloc void *ptr = (void *)malloc(size); #define malloc(p) mallocz((p),__LINE__) Insert((unsigned int)ptr, line); return(ptr); }; static inline void mydelz(void *p) { RemoveOnFree((int)p); #undef free free(p); #define free(p) freez((p)) };
Now, if you want to use this “library” in your code, you save it to file and on you code you just import it and then call to show what you forgot to make .