Что плохого в таком использовании размещения new []? do

Рассмотрим программу ниже. Это было упрощено из сложного случая. Он не может удалить предыдущую выделенную память, если я не удалю виртуальный деструктор в классе Obj. Я не понимаю, почему два адреса из вывода программы отличаются, только если присутствует виртуальный деструктор.

// 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;
}

Это результат работы программы в моей реализации, когда присутствует виртуальный деструктор:

Адрес выделенной памяти начинается с: 0x8895008 Память, которая должна быть освобождена, начинается с: 0x889500c

RUN FAILED ( значение выхода 1)

Пожалуйста, не спрашивайте, что программа должна делать. Как я уже сказал, это связано с более сложным случаем, когда Arena представляет собой интерфейс для различных типов памяти. В этом примере память просто выделяется и освобождается из кучи.

7
задан Martin 24 November 2011 в 20:58
поделиться