配置 new の結果は常に、配置 new に提供するメモリ ポインターと同じように見えます。GCCでは、これは仮想関数を持つクラスにも当てはまるようです。たとえば...
#include <iostream>
#include <vector>
using namespace std;
class A
{
public:
int a;
virtual ~A() {}
};
int main()
{
void *mem = malloc(sizeof(A));
A* ptr = new(mem) A();
cout << "sizeof(T) = " << sizeof(A) << endl;
cout << "mem = " << mem << endl;
cout << "ptr = " << ptr << endl;
cout << "addr a = " << &(ptr->a) << endl;
ptr->~A();
free(mem);
return 0;
}
このプログラムの出力は (注: 64 ビット Linux)...
sizeof(T) = 16
mem = 0x1a41010
ptr = 0x1a41010
addr a = 0x1a41018
C++ は mem と ptr が同一であることを保証しますか、それとも GCC の偶然の一致ですか? 大規模な移植可能なプログラムでは、mem と ptr の両方を保存する必要がありますか、それともどちらか一方だけを保存して必要に応じてキャストできますか?
質問を少し明確にするために、メモリ アロケーターは、割り当てられたブロックのサイズを、ポイントされたメモリ ブロックの前の単語に入れることがあることを知っています。C++ コンパイラは、そのようなトリックを使用して、オブジェクト ポインタが指すメモリ ブロックの前の単語に VMT ポインタを配置することを許可されていますか? この場合、mem と ptr は異なります。