gpt4 book ai didi

c++ - placement new 何时明确定义,调用 placement new 时现有类型会发生什么?

转载 作者:太空狗 更新时间:2023-10-29 20:58:37 30 4
gpt4 key购买 nike

我看过一些 placement new 的例子,但对各种类型内部发生的事情有点困惑。

一个简单的例子:

using my_type       = std::string;
using buffer_type = char;

buffer_type buffer[1000];
my_type* p{ new (buffer) my_type() };

p->~my_type();

据我所知,这是有效的,尽管我担心 buffer[] 的字符数组会发生什么。只要我在内存中就地创建新对象后不以任何形式访问变量 buffer 似乎就可以这样做。

为了简单起见,我不关心这里与正确对齐有关的任何事情,或者调用 placement new 时可能出错的任何其他主题,除了:原始类型会发生什么?我可以使用另一种类型,例如 buffer_type = int 来实现类似的效果(忽略实际占用多少内存的可能性)?任何 POD 都像 buffer_type 一样安全吗?非 POD 类型如何?我是否必须以某种方式告诉编译器 char 数组不再有效? my_type 可以在此处或不在此处是否有限制?

这段代码是否按照我的预期执行,它是否定义良好,是否有任何微小的修改可以保持它的定义良好或将其分解为未定义的行为?

最佳答案

what happens to the original type?

你是说原始对象?它被摧毁,也就是说,它的生命周期结束了。类型为 buffer_type [1000] 的数组对象的生命周期在您重新使用其存储后立即结束。

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; however, if there is no explicit call to the destructor or if a delete-expression (5.3.5) is not used to release the storage, the destructor shall not be implicitly called and any program that depends on the side effects produced by the destructor has undefined behavior.

请注意,这意味着我们不应该为缓冲区使用具有非平凡析构函数的东西:元素的析构函数在它定义的范围的末尾被调用。例如std::string 作为元素类型,这将暗示对不存在的数组子对象的析构函数调用,这显然会触发未定义的行为。

If a program ends the lifetime of an object of type T with […] automatic (3.7.3) storage duration and if T has a non-trivial destructor, the program must ensure that an object of the original type occupies that same storage location when the implicit destructor call takes place; otherwise the behavior of the program is undefined.

为了避免这种情况,您必须在使用完缓冲区后将 std:string 构造到该缓冲区中,这看起来确实很荒谬。

Is any POD safe as buffer_type?

我们不一定需要 POD - 他们有很多在这里没有必要的要求。唯一困扰我们的是构造函数和析构函数。
类型析构函数是否微不足道(或者对于数组,数组元素类型的析构函数)很重要。构造函数也很简单也是可行的。

POD 类型感觉更安全,因为它们满足这两个要求并且很好地传达了“裸存储”的概念。

Are there restrictions on what my_type could be or not be here?

是的。它应该是一个对象类型。它可以是任何对象类型,但不能是引用。

关于c++ - placement new 何时明确定义,调用 placement new 时现有类型会发生什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27175952/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com