Можно ли использовать новые массивы для переноса?

Можно ли реально использовать размещение нового в переносимом коде при использовании его для массивов?

Похоже, что указатель, который вы получаете от 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 большой, последний элемент в массиве записывается в нераспределенную кучу.

Итак, вопрос в том, можете ли вы узнать, сколько дополнительных затрат требует ваша реализация для безопасного размещения new []? В идеале мне нужна техника, которая переносима между разными компиляторами. Обратите внимание, что, по крайней мере в случае VC, накладные расходы различаются для разных классов. Например, если я удаляю виртуальный деструктор в примере, адрес, возвращаемый из new [], совпадает с адресом, который я передаю.

Ответы на вопрос(7)

Ваш ответ на вопрос