Rozważ poniższy program. Zostało uproszczone ze złożonego przypadku. Nie powiedzie się podczas usuwania poprzednio przydzielonej pamięci, chyba że usunę wirtualny destruktor z klasy Obj. Nie rozumiem, dlaczego dwa adresy z wyjścia programu różnią się, tylko jeśli obecny jest wirtualny destruktor.Co jest nie tak z użyciem nowego miejsca docelowego []? do
// 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;
}
Jest to wyjście z programu w mojej realizacji, gdy wirtualny destruktor jest obecny:
Przydzielony adres pamięci zaczyna się na: 0x8895008 Pamięć być zwalniane rozpoczyna się pod adresem: 0x889500c
URUCHOMIONA URUCHOMIENIE (wartość wyjściowa 1)
Proszę nie pytać, jaki program powinien mieć o. Jak powiedziałem, pochodzi z bardziej złożonego przypadku, w którym Arena jest interfejsem dla różnych typów pamięci. W tym przykładzie pamięć jest po prostu przydzielana i zwalniana ze sterty.
pamiętać, że * do * potrzebują umieszczenie tablicy dopasowanie usunąć w przypadku nowej ekspresji zgłasza wyjątek. –