Sunteți pe pagina 1din 13

Finding Memory Leaks

The new operator and operator new


When allocating memory using new, e.g.
Student *ps = new Student(Yossi Cohen); int *pi = new int[100];

The new operator (or new[] operator) is called The new ( new[] ) operator
Calls operator new ( operator new[]) to allocate memory Calls a constructor (default ctor, for arrays)

Overloading operator new


The new operator cannot be overloaded operator new and operator new[] can be overloaded in two ways:
For a given class As global operators, which will apply for all types and classes for which these operators were not overloaded in the class.

When overloading operator new, one should also overload operator new[]. operator new can be overloaded with extra parameters

The delete operator and operator delete


When releasing memory using delete, e.g.
Delete ps; delete []pi;

The delete operator (or delete[] operator) is called The delete ( delete[] ) operator
Calls the destructor (destructors for arrays) Calls operator delete ( operator delete[]) to release memory

Overloading operator delete


The delete operator cannot be overloaded operator delete and operator delete[] can be overloaded in two ways:
For a given class As global operators, which will apply for all types and classes for which these operators were not overloaded in the class.

When overloading operator delete, one should also overload operator delete[]. operator delete can be overloaded with extra parameters

Overloading operator new and operator delete


operator new and operator delete can be overloaded to keep track of all memory allocations in a program In the following example the global versions of these operators are overloaded

// CatchMemoryLeak.h Created by Yosi Halakhmi, private consultant


#ifndef CATCHMEMORYLEAK_H #define CATCHMEMORYLEAK_H #include <stdlib.h>

void saveInStorage(

unsigned long addr, unsigned long nBytes, const char *fname, unsigned long lnum); void removeFromStorage(unsigned long addr); void reportUnreleasedHeap();
#ifdef _DEBUG inline void * operator new( { unsigned int size, const char *fileName, int line)

void *ptr = (void *)malloc(size); saveInStorage((unsigned long)ptr, size, fileName, line); return(ptr);

inline void * operator new[](unsigned int size, const char * fileName, int line) { void *ptr = (void *)malloc(size); saveInStorage((unsigned long)ptr, size, fileName, line); return(ptr); }

inline void operator delete(void* ptr) { removeFromStorage((unsigned long)ptr); free(ptr); } inline void operator delete[](void* ptr) { removeFromStorage((unsigned long)ptr); free(ptr); } #endif // _DEBUG #ifdef DEBUG_NEW #undef DEBUG_NEW #endif // MFC macro

#ifdef _DEBUG #define new new(__FILE__, __LINE__) #endif

#endif

// CATCHMEMORYLEAK_H

// CatchMemoryLeak.cpp #include <iostream> #include <fstream> #include <map> #include <string> using namespace std; struct HeapInfo_s { string unsigned long unsigned long unsigned long }; fileName; lineNo; adrInHeap; nBytes;

typedef map<unsigned long, HeapInfo_s* > heapStorage_t; heapStorage_t* heapStorage; // global variable is initialized to 0

void saveInStorage(unsigned long addr, unsigned long nBytes, const char* fileName, unsigned long lineNo) { HeapInfo_s* hInfo; if(!heapStorage) { heapStorage = new(heapStorage_t); } hInfo = new (HeapInfo_s); hInfo->adrInHeap = addr; hInfo->fileName = fileName; hInfo->lineNo = lineNo; hInfo->nBytes = nBytes; (*heapStorage)[addr] = hInfo;

void removeFromStorage(unsigned long addr) { if( heapStorage) { heapStorage_t::iterator itor; itor = heapStorage->find(addr); if (itor != heapStorage->end() ) { heapStorage->erase((itor)); } } } void reportUnreleasedHeap() { ofstream ofs("Leaks.txt"); if( heapStorage) { heapStorage_t::iterator itor; for(itor = heapStorage->begin(); itor != heapStorage->end(); ++itor) { ofs << "File Name : " << (*itor).second->fileName << endl; ofs << "Line No : " << (*itor).second->lineNo << endl; ofs << "Number of unreleased bytes : " << (*itor).second->nBytes << endl; ofs << endl; }

// TestMemoryLeak.cpp #include <iostream> #include "CatchMemoryLeak.h" using namespace std; class X { char c; int y; public: X(char a=0, int b=0):c(a),y(b){} }; void func() { float* pf = new float; // memory leak } int main() { char* ip = new char; int* ip1 = new int[100]; int* ip2 = (int*)malloc(50*sizeof(int)); X* px=new X(a,1); // memory leak func(); delete ip; delete []ip1; reportUnreleasedHeap(); return 0;

Report:
File Name : testmemoryleak.cpp Line No : 23 Number of unreleased bytes : 8
File Name : testmemoryleak.cpp Line No : 15 Number of unreleased bytes : 4

Alignment of int

Discussion
How can we keep track of possible deletions of already freed memory? How can we keep track of overwriting data below or above the allocated block?

S-ar putea să vă placă și