Created
November 16, 2016 19:40
-
-
Save phg1024/2707e59daf91bc7bf39cd40cb2f0d364 to your computer and use it in GitHub Desktop.
Memory tracker with overloaded new/delete.
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
#include <iostream> | |
#include <memory> | |
#include <cstdlib> | |
#include <unordered_map> | |
#include <stdexcept> | |
using namespace std; | |
template <int MAX_TABLE_SIZE=1024> | |
class MemTracker { | |
pair<void*, bool> mem_tbl[MAX_TABLE_SIZE]; | |
int mem_counter; | |
static MemTracker* instance; | |
void init_table() { | |
for(int i=0;i<MAX_TABLE_SIZE;++i) mem_tbl[i] = make_pair(nullptr, false); | |
} | |
int hash(void* ptr) { | |
int pos = reinterpret_cast<uint64_t>(ptr) % MAX_TABLE_SIZE; | |
cout << "hash loc = " << pos << endl; | |
return pos; | |
} | |
public: | |
MemTracker() : mem_counter(0) { | |
init_table(); | |
} | |
bool set(void* ptr) { | |
int pos = hash(ptr); | |
int pos0 = pos; | |
bool good = true; | |
while(mem_tbl[pos].second) { | |
++pos; | |
pos %= MAX_TABLE_SIZE; | |
cout << "probing position " << pos << endl; | |
if(pos == pos0) { | |
good = false; | |
break; | |
} | |
} | |
if(!good) return false; | |
cout << "storing pointer " << ptr << " at " << pos << endl; | |
mem_tbl[pos] = make_pair(ptr, true); | |
++mem_counter; | |
return true; | |
} | |
bool reset(void* ptr) { | |
if(ptr == nullptr) return true; | |
int pos = hash(ptr); | |
int pos0 = pos; | |
bool good = true; | |
while(mem_tbl[pos].first != ptr) { | |
++pos; | |
pos %= MAX_TABLE_SIZE; | |
cout << "probing position " << pos << endl; | |
if(pos == pos0) { | |
good = false; | |
break; | |
} | |
} | |
if(!good) return false; | |
cout << "removing pointer " << ptr << " at " << pos << endl; | |
mem_tbl[pos] = make_pair(nullptr, false); | |
--mem_counter; | |
return true; | |
} | |
int count() const { | |
return mem_counter; | |
} | |
}; | |
MemTracker<15> pool; | |
void* operator new(size_t sz) throw() { | |
try { | |
auto ptr = malloc(sz); | |
cout << "allocating " << sz << " bytes at " << ptr << endl; | |
if(pool.set(ptr)) return ptr; | |
else { | |
free(ptr); | |
throw bad_alloc(); | |
} | |
} | |
catch(exception& e) { | |
cout << "Critical error: " << e.what() << endl; | |
exit(1); | |
} | |
} | |
void operator delete(void* ptr) { | |
try{ | |
cout << "deallocating at " << ptr << endl; | |
if(pool.reset(ptr)) free(ptr); | |
else throw runtime_error("deleting an uninitialized pointer."); | |
} | |
catch(exception& e) { | |
cout << "Critical error: " << e.what() << endl; | |
} | |
} | |
int main(int argc, char** argv) { | |
std::cout << "Hello World!\n"; | |
int n = 15; | |
int* a[n]; | |
for(int i=0;i<n;++i) { | |
a[i] = new int; | |
cout << pool.count() << " allocated." << endl; | |
} | |
for(int i=0;i<n;++i) delete a[i]; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment