当前位置:  开发笔记 > 编程语言 > 正文

是否可以以便携方式使用新的数组放置?

如何解决《是否可以以便携方式使用新的数组放置?》经验,为你挑选了1个好方法。

在将它用于数组时,是否可以在便携式代码中实际使用新的放置?

看来你从new []返回的指针并不总是和你传入的地址相同(5.3.4,标准中的注释12似乎证实这是正确的),但是我不知道你是怎么回事如果是这种情况,可以为数组分配一个缓冲区.

以下示例显示了该问题.使用Visual Studio编译,此示例导致内存损坏:

#include 
#include 

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 []返回的地址与我传入的地址相同.



1> OJ...:

我个人倒有没有使用贴片阵列上新的选项去,而是在阵列中使用新的安置在每个项目单独.例如:

int main(int argc, char* argv[])
{
  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);

  // dont forget to destroy!
  for(int i = 0; i < NUMELEMENTS; ++i)
  {
    pA[i].~A();
  }    

  delete[] pBuffer;

  return 0;
}

无论您使用哪种方法,请确保在删除pBuffer之前手动销毁阵列中的每个项目,因为最终可能会泄漏;)

注意:我没有编译它,但我认为它应该工作(我在没有安装C++编译器的机器上).它仍然表明了点:)希望它在某种程度上有所帮助!


编辑:

它需要跟踪元素数量的原因是,当您在数组上调用delete并确保在每个对象上调用析构函数时,它可以迭代它们.如果它不知道有多少它将无法做到这一点.


@JustinTime标准本身的缺陷是允许将开销应用于`void*operator new [](std :: size_t count,void*ptr);`当这个运算符被称为"no-op"时(没有分配)并且还清楚地知道这个操作符或其标量兄弟返回的指针不能传递给`delete`或`delete []`,要求程序员手动销毁每个元素.
@JustinTime这是一个缺陷似乎没有人盯着看.
推荐阅读
135369一生真爱_890
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有