Skip to content

Instantly share code, notes, and snippets.

@phg1024
Created November 16, 2016 19:40
Show Gist options
  • Save phg1024/2707e59daf91bc7bf39cd40cb2f0d364 to your computer and use it in GitHub Desktop.
Save phg1024/2707e59daf91bc7bf39cd40cb2f0d364 to your computer and use it in GitHub Desktop.
Memory tracker with overloaded new/delete.
#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