将其用于数组时,是否可以实际使用可移植代码中的新位置?
看来您从 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[] 返回的地址与我传入的地址相同。