它是否在同一地址多次定位/合法? [英] Is it well-defined/legal to placement-new multiple times at the same address?

查看:195
本文介绍了它是否在同一地址多次定位/合法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

(注意:这个问题的动机是试图提出预处理器hackery生成一个无操作分配来回答这个其他问题:



< a href =http://stackoverflow.com/questions/7522949/c-macro-that-accent-new-object/7523078#7523078>强调新物件的C ++巨集



...请记住!)



这是一个设计类:

  class foo {
private:
int bar;
public:
foo(int bar):bar(bar)
{std :: cout< construct foo#< bar<< std :: endl; }
〜foo()
{std :: cout< destruct foo#< bar<< std :: endl; }
};

...我将这样分配:

  //注意:对于对齐,不要使用char * buffer with new char [sizeof(foo)]! 
void * buffer = operator new(sizeof(foo));

foo * p1 = new(buffer)foo(1);
foo * p2 = new(buffer)foo(2);

/ * p1->〜foo(); * / / *根据规范不必要和有问题在gen。 case * /
p2->〜foo();

在gcc上,我得到了期望结果:

  construct foo#1 
construct foo#2
destruct foo#2

这是伟大的,但编译器/运行时可以拒绝这个滥用,仍然在规范的右边?



如何使用线程?如果我们实际上并不关心这个类的内容(假设它只是一个虚拟对象)它将至少不会崩溃,如在更简单的应用程序,促使这与POD int?

$在同一内存块上多次执行b $ b

解决方案

Peforming placement-new 此外,尽管奇怪它可能听起来,你甚至不需要破坏已经驻留在该内存中的对象(如果有)。标准明确允许在3.8 / 4中


4 程序可以通过重复使用来结束任何对象的生命周期对象占用的存储
,或者通过显式调用
的析构函数来获得具有非平凡析构函数的类类型的对象。对于具有非平凡析构函数的类类型的对象
,程序不需要
在对象占用的
被重新使用或释放​​之前明确地调用析构函数; [。 ..]


换句话说,你有责任考虑不为某些对象调用析构函数的后果。 / p>

但是,不允许在代码中对同一对象两次调用析构函数。一旦你在同一内存区域中创建了第二个对象,你就有效地终止了第一个对象的生命周期(即使你从来没有调用它的析构函数)。现在你只需要破坏第二个对象。


(Note: this question was motivated by trying to come up with preprocessor hackery to generate a no-op allocation to answer this other question:

C++ Macro that accent new object

...so bear that in mind!)

Here's a contrived class:

class foo {
private:
    int bar;
public:
    foo(int bar) : bar (bar)
        { std::cout << "construct foo #" << bar << std::endl; }
    ~foo()
        { std::cout << "destruct foo #" << bar << std::endl; }
};

...which I will allocate like this:

// Note: for alignment, don't use char* buffer with new char[sizeof(foo)] !
void* buffer = operator new(sizeof(foo));

foo* p1 = new (buffer) foo(1);
foo* p2 = new (buffer) foo(2);

/* p1->~foo(); */ /* not necessary per spec and problematic in gen. case */
p2->~foo();

On the gcc I've got around, I get the "expected" result:

construct foo #1
construct foo #2
destruct foo #2

Which is great, but could the compiler/runtime reject this as an abuse and still be on the right side of the spec?

How about with threading? If we don't actually care about the contents of this class (let's say it's just a dummy object anyway) will it at least not crash, such as in the even simpler application which motivated this with a POD int?

解决方案

Peforming placement-new several times on the same block of memory is perfectly fine. Moreover, however strange it might sound, you are not even requred to destruct the object that already resides in that memory (if any). The standard explicitly allows that in 3.8/4

4 A program may end the lifetime of any object by reusing the storage which the object occupies or by explicitly calling the destructor for an object of a class type with a non-trivial destructor. For an object of a class type with a non-trivial destructor, the program is not required to call the destructor explicitly before the storage which the object occupies is reused or released;[...]

In other words, it is your responsibility to take into account the consequences of not calling the destructor for some object.

However, calling the destructor on the same object twice as you do in your code is not allowed. Once you created the second object in the same region of memory, you effectively ended the lifetime of the first object (even though you never called its destructor). Now you only need to destruct the second object.

这篇关于它是否在同一地址多次定位/合法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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