TITLE: An interesting new/delete scheme PROBLEM: maxtal@physics.su.OZ.AU (John Max Skaller), 29 Jun 93 A solution requires a 'smart delete' that can figure out how an object was allocated, and deallocate it accordingly. Again: a good solution would be well appreciated, especially one in the existing language. Anyone? RESPONSE: jimad@microsoft.com (Jim Adcock), 30 Jun 93 Microsoft Corporation Obviously one must somehow mark the allocation such that the correct deallocation can be performed via the one available delete function. Clearly a variety of time/space tradeoffs are available. Below find the trivial and fast tradeoff of "marking" the allocation with the address of the particular "free'ing" function to be called from operator delete. Two different flavors of new are presented for example, one just mallocs, the other records and echos a variety of debugging information. Corresponding "free" routines are presented which automatically get called from the one delete. Both news and both free are presented in the base class, but that need not be the case. Similar global new/free approaches are possible. #include #include #include #include typedef void FDEL(void* p, size_t size); typedef FDEL* PFDEL; class A { int a; static void sfree(void* p, size_t size); static void sfreedebug(void* p, size_t size); public: virtual ~A() {} void* operator new(size_t size); void operator delete(void* p, size_t size); void* operator new(size_t size, int iline, char* szfile); // debug version }; void A::operator delete(void* p, size_t size) { char* pb = (char*) p; pb -= sizeof(PFDEL); PFDEL pfdel = *(PFDEL*)pb; (*pfdel)(pb, size); } void A::sfree(void* p, size_t size) { free(p); } void* A::operator new(size_t size) { char* pb = (char*) malloc(size + sizeof(PFDEL)); *(PFDEL*)pb = &sfree; return (pb + sizeof(PFDEL)); } struct DEBUGHDR { size_t size; int iline; char* szfile; PFDEL pfdel; }; void A::sfreedebug(void* p, size_t size) { char* pb = (char*) p; pb += (sizeof(PFDEL) - sizeof(DEBUGHDR)); DEBUGHDR* phdr = (DEBUGHDR*) pb; assert(size == phdr->size); cout << "freeing " << phdr->size << " bytes allocated at line " << phdr->iline << " in file " << phdr->szfile << "\n"; free(pb); } void* A::operator new(size_t size, int iline, char* szfile) { char* pb = (char*) malloc(size + sizeof(DEBUGHDR)); DEBUGHDR* phdr = (DEBUGHDR*) pb; phdr->size = size; phdr->iline = iline; phdr->szfile = szfile; phdr->pfdel = &sfreedebug; cout << "new'ing " << phdr->size << " bytes allocated at line " << phdr->iline << " in file " << phdr->szfile << "\n"; return (pb + sizeof(DEBUGHDR)); } class B : public A { double b; }; main() { A* pa1 = new A; B* pb1 = new B; A* pa2 = new(__LINE__, __FILE__) A; B* pb2 = new(__LINE__, __FILE__) B; delete pa1; delete pb1; delete pa2; delete pb2; return 0; }