Last active
March 12, 2019 11:27
-
-
Save danielSanchezQ/06825e9526d971cf4194d7c0f3e9d0d6 to your computer and use it in GitHub Desktop.
Memory tracking utility
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef _MEM_LICKER_ | |
#define _MEM_LICKER_ | |
#include <unordered_map> | |
#include <iostream> | |
#include <string> | |
using namespace std; | |
using ptr = void*; | |
struct PtrData | |
{ | |
string file; | |
int line; | |
size_t size; | |
PtrData(string f, int l, size_t s) | |
{ | |
file = f; | |
line = l; | |
size = s; | |
} | |
}; | |
using LeakData = pair<ptr, PtrData>; | |
class MemLicker | |
{ | |
private: | |
static MemLicker* instance; | |
unordered_map<ptr, PtrData> mLeaks; | |
MemLicker() : mLeaks() {}; | |
public: | |
~MemLicker() { delete instance; instance = nullptr; } | |
static MemLicker* getLicker() | |
{ | |
if (instance == nullptr) { instance = new MemLicker(); } | |
return instance; | |
}; | |
template<class T, typename ...Args> | |
T* allocate(string file, int line, size_t size = 0, Args&&...args) | |
{ | |
T* ret; | |
if(size > 0) ret = new T[size]; | |
else ret = new T(args...); | |
mLeaks.insert(LeakData(ret, PtrData(file, line, size > 0 ? sizeof(T)*size : sizeof(T)))); | |
return ret; | |
} | |
void deallocate(ptr p) | |
{ | |
auto pData = mLeaks.find(p); | |
mLeaks.erase(p); | |
if (pData->second.size > 0) delete[] p; | |
else delete p; | |
} | |
void report() | |
{ | |
for(LeakData ldata : mLeaks) | |
{ | |
stringstream s; | |
//s << ldata.second.file << "(" << ldata.second.line << "):" << " Leaked " << ldata.second.size << "bytes @ memory address: " << ldata.first << endl; | |
OutputDebugStringA(s.str().c_str()); | |
//cout << s.str() << endl; | |
} | |
} | |
}; | |
MemLicker* MemLicker::instance = nullptr; | |
#if DEBUG > 0 | |
#define NEW(T, ...) MemLicker::getLicker()->allocate<T> (__FILE__, __LINE__, 0, ##__VA_ARGS__) | |
#define NEWBLOCK(T, S) MemLicker::getLicker()->allocate<T> (__FILE__, __LINE__, S) | |
#define DELETE(P) MemLicker::getLicker()->deallocate(P) | |
#define DELETEBLOCK(P) MemLicker::getLicker()->deallocate(P) | |
#define REPORT() MemLicker::getLicker()->report() | |
#else | |
#define NEW(T, ...) new T(__VA_ARGS__) | |
#define NEWBLOCK(T, S) new T[S] | |
#define DELETE(P) delete P | |
#define DELETEBLOCK(P) delete[] P | |
#define REPORT() | |
#endif | |
#endif // !_MEM_LICKER_ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment