可以放置数组新的便携式的方式来使用? [英] Can placement new for arrays be used in a portable way?

查看:140
本文介绍了可以放置数组新的便携式的方式来使用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否有可能将其用于阵列时,实际利用放置在便携code新的?

Is it possible to actually make use of placement new in portable code when using it for arrays?

看来,指针你从全新的背[]并不总是一样的,你在传递地址(5.3.4,注意12的标准似乎证实,这是正确的),但我不看看你能如何分配缓冲区的数组进去,如果是这样的话。

It appears that the pointer you get back from new[] is not always the same as the address you pass in (5.3.4, note 12 in the standard seems to confirm that this is correct), but I don't see how you can allocate a buffer for the array to go in if this is the case.

下面的例子说明问题了。与Visual Studio编译的,这个例子会导致内存崩溃:

The following example shows the problem. Compiled with Visual Studio, this example results in memory corruption:

#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个大,数组中的最后一个元素被写入到未分配堆。

Looking at the memory, the compiler seems to be using the first four bytes of the buffer to store a count of the number of items in it. This means that because the buffer is only sizeof(A)*NUMELEMENTS big, the last element in the array is written into unallocated heap.

所以,问题是,你可以找到你的实现多少额外的开销要以使用新的位置[]安全?理想情况下,我需要一种技术是不同的编译器之间移植。需要注意的是,至少在VC的情况下,开销似乎不同类别不同。举例来说,如果我删除虚拟析构函数的例子中,该地址从新返回了[]是一样的我通过在地址。

So the question is can you find out how much additional overhead your implementation wants in order to use placement new[] safely? Ideally, I need a technique that's portable between different compilers. Note that, at least in VC's case, the overhead seems to differ for different classes. For instance, if I remove the virtual destructor in the example, the address returned from new[] is the same as the address I pass in.

推荐答案

我个人会去与不使用放置在阵列上新的选择,而是在阵列中使用新的安置在每个项目单独。例如:

Personally I'd go with the option of not using placement new on the array and instead use placement new on each item in the array individually. For example:

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的,因为你可以与泄漏结束;)

Regardless of the method you use, make sure you manually destroy each of those items in the array before you delete pBuffer, as you could end up with leaks ;)

注意的:我没有这个选项编译,但我认为它应该工作(我就是没有安装C ++编译器的机器上)。它仍然表示点:)希望这有助于以某种方式!

Note: I haven't compiled this, but I think it should work (I'm on a machine that doesn't have a C++ compiler installed). It still indicates the point :) Hope it helps in some way!

编辑:

它需要保持元件的数目的轨道的原因是,使得它可以遍历它们当调用删除在阵列上,并确保析构被称为在每个对象。如果它不知道有多少,将不能够做到这一点。

The reason it needs to keep track of the number of elements is so that it can iterate through them when you call delete on the array and make sure the destructors are called on each of the objects. If it doesn't know how many there are it wouldn't be able to do this.

这篇关于可以放置数组新的便携式的方式来使用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆