Результат размещения 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 будут разными.