通过新的展示位置开始创建的普通类型的寿命在什么时候开始? [英] At what point does the lifetime of a trivial type created by placement-new start?

查看:83
本文介绍了通过新的展示位置开始创建的普通类型的寿命在什么时候开始?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在进入动态内存期间,在我看来,琐碎的类型如何开始其生命似乎是矛盾的.考虑一下片段

During a dive into dynamic memory, it occurred to me it appears contradictory how trivial types begin their lifetime. Consider the snippet

void* p = ::operator new(sizeof(int));  // 1
// 2
new (p) int; // 3

int何时开始使用?

  1. 仅获取存储,::operator new被指定为具有效果(来自

  1. Only acquires storage, ::operator new is specified to have the effect (from [new.delete.single])

由new表达式调用的分配函数,用于分配存储的大小字节. [...]分配适当对齐的存储空间,以表示该大小的任何对象,前提是该对象的类型不具有新扩展的对齐方式.

The allocation functions called by a new-expression to allocate size bytes of storage. [...] allocates storage suitably aligned to represent any object of that size provided the object's type does not have new-extended alignment.

鉴于获取存储是不够的创建对象时,int不能在此处开始其生存期.

Given that acquiring storage is insufficient in creating an object, the int cannot have begin its lifetime here.

这时,已经获取了int的适当存储.

At this point, suitbale storage for the int has been acquired.

int是通过放置新位置创建的.但是不知何故,它的生存期从这里开始,因为它来自 [basic.life]

The int is created by placement new. But somehow its lifetime didn't begin here, since from [basic.life]

[...]如果某个对象属于类或聚合类型,并且该对象或其子对象之一是由普通的默认构造函数以外的构造函数初始化的,则称该对象具有非空初始化.类型为T的对象的生存期始于以下时间:

[...] An object is said to have non-vacuous initialization if it is of a class or aggregate type and it or one of its subobjects is initialized by a constructor other than a trivial default constructor. The lifetime of an object of type T begins when:

    获得具有T类型的正确对齐方式和大小的
  • 存储,并且

  • storage with the proper alignment and size for type T is obtained, and

如果对象具有非空初始化,则其初始化完成[...]

if the object has non-vacuous initialization, its initialization is complete [...]

int既不是类也不是聚合类型,因此具有空虚的初始化.因此,仅第一个项目符号适用.但是,这显然不是在获得存储时发生的,因此不可能在其寿命开始时发生.

int is neither a class nor aggregate type, hence it has vacuous initialization. Therefore only the first bullet applies. However, this is clearly not when storage is obtained and therefore cannot be when its lifetime starts.

某些上下文

分配器需要返回内存而无需构造其元素.但是,对于琐碎的类型来说,这是没有意义的. a.allocate(n)a类型为T的分配器对象的作用是

Some context

Allocators are required to return memory without constructing its elements. Yet this doesn't make sense with trivial types. The effects of a.allocate(n) with a an allocator object for type T is

T类型的n对象分配了内存,但未构造对象.

Memory is allocated for n objects of type T but objects are not constructed.

推荐答案

从技术上讲, new-expression 始终会获得存储.代码new(p) int都获取了存储并创建了一个对象,并且根据[basic.life]/1,对象的生存期从new(p) int获得存储开始.

Technically, the new-expression always obtains storage. The code new(p) int both obtains storage and creates an object, and according to [basic.life]/1, the object's lifetime began when new(p) int obtained the storage.

根据N4659 [expr.new],代码new(p) int生成对分配函数::operator new(sizeof(int), p)的调用.在[new.delete.placement]下,标准库定义了这样一个函数:

According to N4659 [expr.new], the code new(p) int generates a call to an allocation function ::operator new(sizeof(int), p). And under [new.delete.placement], the standard library defines such a function:

void* operator new(std::size_t size, void* ptr) noexcept;

返回: ptr.

备注:故意不执行其他任何操作.

Remarks: Intentionally performs no other action.

尽管不执行其他任何操作",并且该实现可能会优化任何实际的函数调用,但对分配函数的此调用仍视为获取由 new-expression创建的对象的存储空间.

Although "no other action" is performed, and probably the implementation will optimize out any actual function call, this call to an allocation function still counts as obtaining storage for the object being created by the new-expression.

这篇关于通过新的展示位置开始创建的普通类型的寿命在什么时候开始?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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