首页 >后端开发 >C++ >数组上的放置 New 能否保证 C 中的可移植性?

数组上的放置 New 能否保证 C 中的可移植性?

Patricia Arquette
Patricia Arquette原创
2024-11-12 16:48:02471浏览

Does Placement New on Arrays Guarantee Portability in C  ?

数组的 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中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn