Можно ли использовать новое размещение в переносном коде при использовании его для массивов?
Похоже, что указатель, который вы возвращаете из нового [], не всегда совпадает с адресом, который вы передаете (5.3.4, примечание 12 в стандарте, похоже, подтверждает, что это правильно), но я не как вы можете выделить буфер для массива, если это так.
В следующем примере показана проблема. Скомпилированный с помощью Visual Studio, этот пример приводит к повреждению памяти:
#include <new>
#include <stdio.h>
class A
{
public:
A() : data(0) {}
virtual ~A() {}
int data;
};
int main()
{
const int NUMELEMENTS=20;
char *pBuffer = new char[NUMELEMENTS*sizeof(A)];
A *pA = new(pBuffer) A[NUMELEMENTS];
// With VC++, pA will be four bytes higher than pBuffer
printf("Buffer address: %x, Array address: %x\n", pBuffer, pA);
// Debug runtime will assert here due to heap corruption
delete[] pBuffer;
return 0;
}
Глядя на память, компилятор, по-видимому, использует первые четыре байта буфера для хранения подсчета количества элементов в нем. Это означает, что поскольку буфер только sizeof(A)*NUMELEMENTS
большой, последний элемент массива записывается в нераспределенную кучу.
Итак, вопрос в том, можете ли вы узнать, сколько дополнительных накладных расходов вы хотите реализовать, чтобы безопасно использовать размещение new []? В идеале мне нужна техника, которая переносится между разными компиляторами. Обратите внимание, что, по крайней мере, в случае VC, накладные расходы, по-видимому, различаются для разных классов. Например, если я удалю виртуальный деструктор в примере, адрес, возвращаемый с нового [], совпадает с адресом, который я передаю.