Consider the program below. It was simplified from a difficult case. It does not delete the previous allocated memory unless I delete the virtual destructor in the Obj class. I do not understand why the two addresses from the output of the program differ only if a virtual destructor is present.
// GCC 4.4 #include <iostream> using namespace std; class Arena { public: void* alloc(size_t s) { char* p = new char[s]; cout << "Allocated memory address starts at: " << (void*)p << '\n'; return p; } void free(void* p) { cout << "The memory to be deallocated starts at: " << p << '\n'; delete [] static_cast<char*> (p); // the program fails here } }; struct Obj { void* operator new[](size_t s, Arena& a) { return a.alloc(s); } virtual ~Obj() {} // if I remove this everything works as expected void destroy(size_t n, Arena* a) { for (size_t i = 0; i < n; i++) this[n - i - 1].~Obj(); if (a) a->free(this); } }; int main(int argc, char** argv) { Arena a; Obj* p = new(a) Obj[5](); p->destroy(5, &a); return 0; }
This is the output of the program in my implementation when a virtual destructor is present:
The allocated memory address starts with: 0x8895008 The memory to be freed begins with: 0x889500c
RUN FAILED (output value 1)
Please do not ask what program he should do. As I said, this comes from a more complex case where Arena is the interface for various types of memory. In this example, the memory is simply allocated and freed from the heap.
Martin
source share