由placement-new创建的普通类型的生命周期从什么时候开始?

2023-12-31

在深入研究动态内存时,我发现琐碎类型如何开始其生命周期似乎是矛盾的。考虑片段

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

什么时候int开始它的生命周期?

  1. 只获取存储,::operator new被指定为具有效果(从[新.删除.单] https://timsong-cpp.github.io/cppwp/support.dynamic#new.delete.single-1)

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

    鉴于获取存储不够 https://stackoverflow.com/questions/40873520/reinterpret-cast-creating-a-trivially-default-constructible-object/40874245#40874245在创建对象时,int它的生命周期不可能从这里开始。

  2. 此时,适合存储int已被收购。

  3. The int是通过放置 new 创建的。但不知怎的,它的生命周期并不是从这里开始的,因为从[基本生活] https://timsong-cpp.github.io/cppwp/basic.life#1

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

    • 存储具有适当的对齐方式和类型大小T得到,并且

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

    int既不是类也不是聚合类型,因此它具有空初始化。因此只有第一条适用。然而,这显然不是获得存储的时间,因此也不可能是其生命周期开始的时间。

一些背景

分配器是必要的 https://timsong-cpp.github.io/cppwp/allocator.requirements#tab:utilities.allocator.requirements返回内存而不构造其元素。但这对于普通类型来说没有意义。的影响a.allocate(n) with a类型的分配器对象T is

内存分配用于n类型对象T但对象并未被构造。


从技术上讲,新表达总是获得存储。代码new(p) int两者都获取存储并创建对象,根据[basic.life]/1,对象的生命周期开始于new(p) int获得存储。

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

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

Returns: ptr.

Remarks:没有故意执行任何其他操作。

尽管“没有执行其他操作”,并且实现可能会优化任何实际的函数调用,但对分配函数的调用仍然算作为正在创建的对象获取存储空间。新表达.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

由placement-new创建的普通类型的生命周期从什么时候开始? 的相关文章

  • 检测到 NuGet 包的版本冲突

    我正在开发 ASP Net core 2 1 Web 应用程序项目 我的解决方案中有 1 个项目和 3 个其他库 它是高级架构 数据访问层 DAL 业务层 BL 公共层 CL 所以我需要添加引用来连接一些库和项目 我已经添加了CL参考我的项
  • Qt - 无法让 lambda 工作[重复]

    这个问题在这里已经有答案了 我有以下功能 我想在其中修剪我的std set
  • 在 C++ 中分割大文件

    我正在尝试编写一个程序 该程序接受一个大文件 任何类型 并将其分成许多较小的 块 我想我已经有了基本的想法 但由于某种原因我无法创建超过 12 kb 的块大小 我知道谷歌等上有一些解决方案 但我更感兴趣的是了解这个限制的根源是什么 然后实际
  • 如何进行带有偏差的浮点舍入(始终向上或向下舍入)?

    我想以偏置舍入浮动 要么总是向下 要么总是向上 代码中有一个特定的点 我需要这个 程序的其余部分应该像往常一样四舍五入到最接近的值 例如 我想四舍五入到最接近的 1 10 倍数 最接近 7 10 的浮点数约为 0 69999998807 但
  • 捕获 foreach 条件中抛出的异常

    我有一个foreach在 foreach 本身的条件下循环期间中断的循环 有没有办法try catch抛出异常然后继续循环的项 这将运行几次 直到异常发生然后结束 try foreach b in bees exception is in
  • 处理 fanart.tv Web 服务响应 JSON 和 C#

    我正在尝试使用 fanart tv Webservice API 但有几个问题 我正在使用 Json Net Newtonsoft Json 并通过其他 Web 服务将 JSON 响应直接反序列化为 C 对象 这里的问题是元素名称正在更改
  • 调试内存不足异常

    在修复我制作的小型 ASP NET C Web 应用程序的错误时 我遇到了 OutOfMemoryException 没有关于在哪里查看的提示 因为这是一个编译时错误 如何诊断此异常 我假设这正是内存分析发挥作用的地方 有小费吗 Thank
  • 获取从属性构造函数内部应用到哪个属性的成员?

    我有一个自定义属性 在自定义属性的构造函数内 我想将属性的属性值设置为属性所应用到的属性的类型 是否有某种方式可以访问该属性所应用到的成员从我的属性类内部 可以从 NET 4 5 using CallerMemberName Somethi
  • 转到 C# WPF 中的第一页

    我正在 WPF 中使用导航服务 为了导航到页面 我使用 this NavigationService Navigate new MyPage 为了返回我使用 this NavigationService GoBack 但是如何在不使用的情况
  • C++派生模板类继承自模板基类,无法调用基类构造函数[重复]

    这个问题在这里已经有答案了 我试图从基类 模板 继承 派生类也是模板 它们具有相同的类型 T 我收到编译错误 非法成员初始化 Base 不是基类或成员 为什么 如何调用基类构造函数 include
  • 范围和临时初始化列表

    我试图将我认为是纯右值的内容传递到范围适配器闭包对象中 除非我将名称绑定到初始值设定项列表并使其成为左值 否则它不会编译 这里发生了什么 include
  • 事件日志写入错误

    很简单 我想向事件日志写入一些内容 protected override void OnStop TODO Add code here to perform any tear down necessary to stop your serv
  • “MyClass”的类型初始值设定项引发异常

    以下是我的Windows服务代码 当我调试代码时 我收到错误 异常 CSMessageUtility CSDetails 的类型初始值设定项引发异常 using System using System Collections Generic
  • 如何排列表格中的项目 - MVC3 视图 (Index.cshtml)

    我想使用 ASP NET MVC3 显示特定类型食品样本中存在的不同类型维生素的含量 如何在我的视图 Index cshtml 中显示它 an example 这些是我的代码 table tr th th foreach var m in
  • UWP 无法在两个应用程序之间创建本地主机连接

    我正在尝试在两个 UWP 应用程序之间设置 TCP 连接 当服务器和客户端在同一个应用程序中运行时 它可以正常工作 但是 当我将服务器部分移动到一个应用程序并将客户端部分移动到另一个应用程序时 ConnectAsync 会引发异常 服务器未
  • Qt - 设置不可编辑的QComboBox的显示文本

    我想将 QComboBox 的文本设置为某些自定义文本 不在 QComboBox 的列表中 而不将此文本添加为 QComboBox 的项目 此行为可以在可编辑的 QComboBox 上实现QComboBox setEditText cons
  • 内核开发和 C++ [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 从我know https stackoverflow com questions 580292 what languages are windo
  • 热重载时调用方法

    我正在使用 Visual Studio 2022 和 C 制作游戏 我想知道当您热重新加载应用程序 当它正在运行时 时是否可以触发一些代码 我基本上有 2 个名为 UnloadLevel 和 LoadLevel 的方法 我想在热重载时执行它
  • 从类模板参数为 asm 生成唯一的字符串文字

    我有一个非常特殊的情况 我需要为类模板中声明的变量生成唯一的汇编程序名称 我需要该名称对于类模板的每个实例都是唯一的 并且我需要将其传递给asm关键字 see here https gcc gnu org onlinedocs gcc 12
  • 如何使用 std::array 模拟 C 数组初始化“int arr[] = { e1, e2, e3, ... }”行为?

    注意 这个问题是关于不必指定元素数量并且仍然允许直接初始化嵌套类型 这个问题 https stackoverflow com questions 6111565 now that we have stdarray what uses are

随机推荐