Результаты поиска
Можно ли использовать новое размещение для массивов переносным способом?
Можно ли на самом деле использовать размещение нового в переносимом коде при использовании его для массивов?
Похоже, что указатель, который вы получаете от new[], не всегда совпадает с адресом, который вы передаете (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 размер, последний элемент массива записывается в нераспределенную кучу.
Итак, вопрос в том, Можете ли вы узнать, сколько дополнительных накладных расходов требуется вашей реализации для безопасного использования placement new[]? В идеале мне нужна техника, переносимая между разными компиляторами. Обратите внимание, что, по крайней мере, в случае VC, накладные расходы, похоже, отличаются для разных классов. Например, если я удаляю виртуальный деструктор в Примере, то адрес, возвращаемый из new[], совпадает с адресом, который я передаю.