You can make the code more generic by having the new and delete operators call a global function that would update the Ptr map, and create/free memory.Quote:
How about a generic method? a template seems to be more accurate here...
Printable View
You can make the code more generic by having the new and delete operators call a global function that would update the Ptr map, and create/free memory.Quote:
How about a generic method? a template seems to be more accurate here...
The following is an example using some template functions.
Code:std::map<const void*, size_t> PtrTracker;
template<typename T>
T* GetTrackerMemory(size_t s)
{
T* ptr = (T*)malloc(sizeof(T)*s);
PtrTracker[ptr] = s;
return ptr;
}
template<typename T>
void FreeTrackerMemory(T* ptr)
{
size_t s = PtrTracker[ptr];
for(T* p = ptr;p < ptr+s;++p)
PtrTracker.erase(p);
free(ptr);
}
template<typename T>
bool IsCreatedByNew(const T* ptr)
{
return (PtrTracker.find(ptr) != PtrTracker.end());
}
class foo {
public:
foo()
{
++Qty;
std::cout << "Passing through constructor " << Qty << std::endl;
}
~foo()
{
--Qty;
std::cout << "Passing through destructor " << Qty << std::endl;
}
void* operator new(size_t)
{
return GetTrackerMemory<foo>(1);
}
void operator delete(void* ptr)
{
FreeTrackerMemory((foo*)ptr);
}
void* operator new[] (size_t s)
{
return GetTrackerMemory<foo>(s);
}
void operator delete[] (void* ptr)
{
FreeTrackerMemory((foo*)ptr);
}
static int Qty;
};
int foo::Qty = 0;
void SomeFunction()
{
foo *pX = new foo;
foo *pXa = new foo[5];
foo NotPtr;
foo NotPtrA[5];
bool t1 = IsCreatedByNew(pXa);
pXa++;
bool t2 = IsCreatedByNew(pXa++);
bool t3 = IsCreatedByNew(pX);
bool t4 = IsCreatedByNew(&NotPtr);
bool t5 = IsCreatedByNew(&NotPtrA[0]);
bool t6 = IsCreatedByNew(&NotPtrA[2]);
delete pX;
pXa--;
pXa--;
delete [] pXa;
bool t7 = IsCreatedByNew(pX);
bool t8 = IsCreatedByNew(pXa++);
}
int main(int, char**)
{
SomeFunction();
return 0;
}
Thank you a lot Axter for your effort.
It's only 1 problem....your code is not so generic...
Why?? If you have more classes ( let's suppose foo2, foo3, foo4 ......) you must modify each of them in order to find out whether an instance of any class is allocated on the heap or not...Am I wrong?
Here is the way a user would be happy to use...
Heap_Test<foo> pXa = new foo[5];
Heap_Test<foo1> pX = new foo;
Heap_Test<foo2> NotPtr;
Heap_Test<foo3> NotPtrA[5];
bool t1 = ::IsCreatedByNew(pXa);
bool t3 = ::IsCreatedByNew(pX);
bool t4 = ::IsCreatedByNew(NotPtr);
bool t5 = ::IsCreatedByNew(NotPtrA[0]);
bool t6 = ::IsCreatedByNew(NotPtrA[2]);
delete [] pXa;
delete pX;
bool t7 = ::IsCreatedByNew(pX);
I think above method involves smart pointers/handle...Unfortunately I cant implement it right now...I hope you will do Axter...
it might be some other better technics...
"If you want to supply an allocator/deallocator pair that works corectly for derived classes you must either supply a virtual destructor in base class or refrain from using the size t in deallocator"
B. Stroustrup "The C++ Programming Language", 3rd edition,
15.6 Free Store
Howdy Vije!
It is not clear why you want to discriminate between stack and heap allocated variables. Try the code below; it may help you.
Regards,Code:class B
{
private: ~B() {}
public: void release() { delete this; } // always on the heap
};
int main()
{
B* hb = new B; // ok
B sb; // error: destructor not visible
// ...
return 0;
}