数组的 Placement New 能否确保可移植性?
虽然placement new 提供了一种在 C 中初始化数组的方法,但它在数组中的使用引入了潜在的潜力可移植性问题。具体来说,从 new[] 获得的指针可能会偏离提供的地址,从而阻碍数组的缓冲区分配。
标准的 5.3.4,注释 12,承认了这种差异,使得分配缓冲区的挑战数组的适当大小。一个示例突出显示了该问题:
int main() { const int NUMELEMENTS = 20; char *pBuffer = new char[NUMELEMENTS * sizeof(A)]; A *pA = new(pBuffer) A[NUMELEMENTS]; // With Visual Studio, pA will be four bytes higher than pBuffer printf("Buffer address: %x, Array address: %x\n", pBuffer, pA); }
在此示例中,编译器似乎在缓冲区的前四个字节中存储了数组元素的计数。因此,会发生内存损坏,因为缓冲区仅分配了 sizeof(A) * NUMELMENTS 字节的空间。
避免可移植性问题:
为了减轻这些可移植性问题,请考虑以下方法:
int main() { const int NUMELEMENTS = 20; char *pBuffer = new char[NUMELEMENTS * sizeof(A)]; A *pA = (A*)pBuffer; for (int i = 0; i < NUMELEMENTS; ++i) { pA[i] = new (pA + i) A(); } printf("Buffer address: %x, Array address: %x\n", pBuffer, pA); }
需要注意的是,放置 new[] 的额外开销可能会因实现和类定义而异。尽管如此,这种手动方法确保了不同编译器之间的可移植性,并且无需动态确定开销。
以上是数组上的放置 New 能否保证 C 中的可移植性?的详细内容。更多信息请关注PHP中文网其他相关文章!