Hãy xem xét chương trình bên dưới. Nó đã được đơn giản hóa từ một trường hợp phức tạp. Nó không thành công khi xóa bộ nhớ được cấp phát trước đó, trừ khi tôi loại bỏ trình phá hủy ảo trong lớp Obj. Tôi không hiểu tại sao hai địa chỉ từ đầu ra của chương trình khác nhau, chỉ khi destructor ảo có mặt.Điều gì xảy ra với việc sử dụng vị trí mới này []? làm
// 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;
}
Đây là sản phẩm của chương trình trong việc thực hiện của tôi khi destructor ảo đang hiện diện:
phân bổ địa chỉ bộ nhớ bắt đầu tại địa chỉ: 0x8895008 Bộ nhớ được deallocated bắt đầu tại địa chỉ: 0x889500c
RUN FAILED (giá trị thoát 1)
Vui lòng không hỏi chương trình được yêu cầu o. Như tôi đã nói nó đến từ một trường hợp phức tạp hơn, nơi Arena là một giao diện cho nhiều loại bộ nhớ khác nhau. Trong ví dụ này, bộ nhớ chỉ được phân bổ và deallocated từ heap.
Lưu ý rằng bạn * làm * cần một mảng vị trí phù hợp xóa trong trường hợp một biểu thức mới ném một ngoại lệ. –