オブジェクトの実際のメモリ位置とは異なる基本クラスポインタが与えられたときに、削除演算子が解放する必要のあるメモリ位置をどのように把握するかを知りたいです。
この動作を自分のカスタムアロケータ/デアロケータに複製したいと思います。
次の階層について考えてみます。
struct A
{
unsigned a;
virtual ~A() { }
};
struct B
{
unsigned b;
virtual ~B() { }
};
struct C : public A, public B
{
unsigned c;
};
タイプCのオブジェクトを割り当て、タイプBのポインターを介して削除したいと思います。これは、演算子deleteの有効な使用法であり、Linux/GCCで機能します。
C* c = new C;
B* b = c;
delete b;
興味深いのは、オブジェクトがメモリ内にどのように配置されているかにより、ポインタ「b」と「c」が実際には異なるアドレスを指していることと、削除演算子が正しいメモリ位置を見つけて解放する方法を「知っている」ことです。
一般に、基本クラスのポインターが与えられた場合、ポリモーフィックオブジェクトのサイズを見つけることはできないことを私は知っています。ポリモーフィックオブジェクトのサイズを見つけてください。オブジェクトの実際のメモリ位置を見つけることも一般的には不可能だと思います。
ノート:
- 私の質問は、new[]とdelete[]がどのように機能するかとは関係ありません。単一オブジェクト割り当ての場合に興味があります。delete []はどのようにしてオペランド配列のサイズを「認識」しますか?。
- デストラクタがどのように呼ばれるかも気になりません。メモリ自体の割り当て解除に興味があります。基本クラスのポインタを削除したときの「delete」のしくみ
- -fno-rttiと-fno-exceptionsを使用してテストしたため、G++は実行時型情報にアクセスできないはずです。