class HeapTracked {
public:
class MissingAddress { };
virtual ~HeapTracked() = 0;
static void* operator new(size_t size);
static void operator delete(void *ptr);
bool isOnHeap() const;
private:
typedef const void* RawAddress;
static list<RawAddress> addresses;
};
// to make the class abstract. the destructor must still be defined, so
// we provide this empty definition.
HeapTracked::~HeapTracked() { };
void* HeapTracked::operator new(size_t size) {
void* memPtr = ::operator new(size);
addresses.push_back(memPtr);
return memPtr;
}
void HeapTracked::operator delete(void *ptr) {
// gracefully handle null pointers
if (ptr == 0) return;
list<RawAddress>::iterator it = find(addresses.begin(), addresses.end(), ptr);
if (it != addresses.end()) {
addresses.erase(it);
::operator delete(ptr);
}
else {
throw MissingAddress();
}
}
bool HeapTracked::isOnHeap() const {
const void* rawAddress = dynamic_cast<const void*>(this);
list<RawAddress>::iterator it = find(addresses.begin(), addresses.end(), rawAddress);
return it != addresses.end();
}
it can not be used with the built-in types. because types like int and char can not inherit from anything. And built-in type have no this pointer.