以下のプログラムを検討してください。複雑なケースから簡素化されています。 Objクラスの仮想デストラクタを削除しない限り、以前に割り当てられたメモリを削除すると失敗します。仮想デストラクタが存在する場合にのみ、プログラムの出力から2つのアドレスが異なる理由はわかりません。プレースメントnew []のこの使用で何が問題になっていますか? 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;
}
仮想デストラクタが存在する場合にこれは私の実装では、プログラムの出力です:
割り当てられたメモリアドレスは、開始時刻:0x8895008 割り当てを解除するメモリの開始時刻:0x889500c
実行に失敗しました(終了値1)
どのようなプログラムを想定しているのですか? o。私が言ったように、Arenaはさまざまなタイプのメモリのためのインターフェイスであるより複雑なケースから来ています。この例では、メモリはちょうど割り当てられ、ヒープから割り当てが解除されます。
注*マッチングの配置配列は、新しい式が例外をスローする場合には削除する必要があります。 –