¿Es posible utilizar la ubicación nueva en el código portátil cuando se usa para arreglos?¿Se puede utilizar la colocación nueva para matrices de forma portátil?
Parece que el puntero que obtiene de nuevo [] no es siempre el mismo que la dirección que ingresa (5.3.4, la nota 12 en el estándar parece confirmar que esto es correcto), pero no lo hago Veamos cómo puede asignar un búfer para que entre la matriz si este es el caso.
El siguiente ejemplo muestra el problema. Compilado con Visual Studio, este ejemplo resulta en daños en la 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;
}
En cuanto a la memoria, el compilador parece estar usando los cuatro primeros bytes de la memoria intermedia para almacenar un recuento del número de elementos que contiene. Esto significa que debido a que el buffer es solo sizeof(A)*NUMELEMENTS
grande, el último elemento de la matriz se escribe en el montón no asignado.
Entonces, la pregunta es ¿puede averiguar cuánto sobrecarga adicional quiere su implementación para poder 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 diferentes clases. Por ejemplo, si elimino el destructor virtual en el ejemplo, la dirección devuelta desde el nuevo [] es la misma que la dirección que paso.
maldiciones ah.Hice una estafa de tu pregunta :([Colocación de array-new requiere sobrecarga no especificada en el búfer?] (Http://stackoverflow.com/questions/8720425/array-placement-new-requires-unspecified-overhead-in-the -buffer) –
Hmm ... si la sobrecarga desaparece cuando elimina el destructor virtual, eso sugeriría que la sobrecarga es probable de la clase 'vtable o de la implementación de VStudio de RTTI. –
O al menos parte de la sobrecarga es. También es posible que la sobrecarga solo se use si la clase tiene un destructor no trivial. –