Finding Memory Leaks. The new operator and operator new When allocating memory using new, e.g....

13
Finding Memory Leaks

Transcript of Finding Memory Leaks. The new operator and operator new When allocating memory using new, e.g....

Page 1: 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.

Finding Memory Leaks

Page 2: 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.

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)

Page 3: 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.

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

Page 4: 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.

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

Page 5: 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.

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

Page 6: 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.

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

Page 7: 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.

// 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);

}

Page 8: 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.

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 // MFC macro#undef DEBUG_NEW#endif

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

#endif // CATCHMEMORYLEAK_H

Page 9: 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.

// CatchMemoryLeak.cpp#include <iostream>#include <fstream>#include <map>#include <string>using namespace std;

struct HeapInfo_s {string fileName;unsigned long lineNo;unsigned long adrInHeap;unsigned long 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;

}

Page 10: 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.

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;

}}

}

Page 11: 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.

// 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;

}

Page 12: 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.

File Name : testmemoryleak.cppLine No : 23Number of unreleased bytes : 8

File Name : testmemoryleak.cppLine No : 15Number of unreleased bytes : 4

Report:

Alignment of int

Page 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.

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?