¿Se puede utilizar la ubicación nueva para matrices de manera portátil?

¿Es posible hacer uso de la ubicación nueva en el código portátil cuando se usa para arreglos?

Parece que el puntero del que regresa de nuevo [] no siempre es el mismo que la dirección que pasa (5.3.4, la nota 12 en la norma parece confirmar que esto es correcto), pero no veo cómo puede asignar un búfer para que la matriz entre si este es el caso.

El siguiente ejemplo muestra el problema. Compilado con Visual Studio, este ejemplo resulta en corrupción de memoria:

#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;
}

Mirando la memoria, el compilador parece estar usando los primeros cuatro bytes del búfer para almacenar un conteo de la cantidad de elementos que contiene. Esto significa que porque el buffer es solosizeof(A)*NUMELEMENTS grande, el último elemento de la matriz se escribe en el montón no asignado.

Entonces, la pregunta es: ¿puede averiguar la sobrecarga adicional que desea su implementación para usar la ubicación nueva [] de forma segura? Idealmente, necesito una técnica que sea portátil entre diferentes compiladores. Tenga en cuenta que, al menos en el caso de VC, la sobrecarga parece diferir para las diferentes clases. Por ejemplo, si quito el destructor virtual en el ejemplo, la dirección devuelta de new [] es la misma que la dirección que paso.

Respuestas a la pregunta(7)

Su respuesta a la pregunta