当委托构造函数抛出异常时,内存是否会自动回收?

2023-12-31

从此:当委托构造函数抛出异常时,析构函数是否被调用? https://stackoverflow.com/q/17657761/14065

class X
{
public:
    X()       {};
    X(int)    : X() { throw std::exception(); }
    X(double)       { throw std::exception(); }
    ~X();
};

那么动态内存呢?通常构造函数中的异常意味着对象没有完全构造,因此内存被清理并且没有丢失。

但上一个问题中的论点是,对象在委托完成后完全构造(或完全初始化)。这对内存回收有何影响?我希望记忆仍然被清理!

int main()
{
    new X(5);        // new called 
                     // delete called because delegate completed.
                     // I assume:  
                     //      Memory re-claimed (because constructor did not complete)
                     //      I assume the C++11 standard adjusted to compensate.
                     //      As a constructor did complete.
}

相比:

int main()
{
    new X(5.0);      // new called 
                     //    Delete **NOT** called
                     // Memory re-claimed (because constructor did not complete)
}

如果内存被清理,则需要从 C++03 规范更改内存何时清理的定义。行为如何改变?


如果构造函数调用new抛出异常,然后分配的内存new被自动释放。委托构造函数在这方面没有任何改变。

If any part of the object initialization described above76 terminates by throwing an exception and a suitable deallocation function can be found, the deallocation function is called to free the memory in which the object was being constructed

— C++11 [expr.new] 5.3.4/18

所描述的“对象初始化的任何部分”包括构造函数调用和传递给构造函数的表达式的求值。

此外,C++98 标准 [C++98 5.4.3/17] 中也同样指定了此行为。委托构造函数的唯一区别在于您的心智模型之前是否基于完全构造的对象。给定的委托构造函数不再等同于释放发生时间的实际规范。


在你的第一个例子中:

new X(5);

事件的顺序是:

  • 称为分配函数
  • X(int) 调用
    • X() 被调用(并成功退出)
    • X(int) 抛出异常
    • ~X() 调用
  • X(int) 通过异常退出
  • 由于对象初始化失败而调用释放函数
  • 异常继续正常传播

以第二个例子为例

new X(5.0);
  • 称为分配函数
  • X(双) 称为
  • X(double) 失败并出现异常
  • 由于对象初始化失败而调用释放函数
  • 异常继续正常传播

您可以通过替换分配和释放函数来观察此行为:

#include <iostream>
#include <cstdlib>
#include <stdexcept>
#include <new>
    
void *operator new(std::size_t s) {
    if (void *ptr = std::malloc(s)) {
        std::cout << "allocation\n";
        return ptr;
    }
    throw std::bad_alloc{};
}

void operator delete(void *ptr) noexcept {
    if (ptr) {
        std::cout << "deallocation\n";
        std::free(ptr);
    }
}

struct S {
    S() {};
    S(int) : S{} { throw std::exception(); }
    S(double) { throw std::exception(); }
    ~S() { std::cout << "destructor\n"; }
};

int main() {
    std::cout << "test 1\n";
    try {
        new S(1);
    } catch(...) {
        std::cout << "exception caught\n";
    }

    std::cout << "test 2\n";
    try {
        new S(1.);
    } catch(...) {
        std::cout << "exception caught\n";
    }
}

该程序的正确输出是:

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

当委托构造函数抛出异常时,内存是否会自动回收? 的相关文章

  • WPF DataGrid 多选

    我读过几篇关于这个主题的文章 但很多都是来自 VS 或框架的早期版本 我想做的是从 dataGrid 中选择多行并将这些行返回到绑定的可观察集合中 我尝试创建一个属性 类型 并将其添加到可观察集合中 它适用于单个记录 但代码永远不会触发多个
  • 在模板类中声明模板友元类时出现编译器错误

    我一直在尝试实现我自己的链表类以用于教学目的 我在迭代器声明中指定了 List 类作为友元 但它似乎无法编译 这些是我使用过的 3 个类的接口 Node h define null Node
  • 调用 McAfee 病毒扫描引擎

    我收到客户的请求 要求使用他们服务器上的 McAfee 病毒扫描将病毒扫描集成到应用程序中 我做了一些调查 发现 McScan32 dll 是主要的扫描引擎 它导出各种看起来有用的函数 我还发现提到了 McAfee Scan Engine
  • 通过引用传递 [C++]、[Qt]

    我写了这样的东西 class Storage public Storage QString key const int value const void add item QString int private QMap
  • 如何从本机 C(++) DLL 调用 .NET (C#) 代码?

    我有一个 C app exe 和一个 C my dll my dll NET 项目链接到本机 C DLL mynat dll 外部 C DLL 接口 并且从 C 调用 C DLL 可以正常工作 通过使用 DllImport mynat dl
  • 需要帮助优化算法 - 两百万以下所有素数的总和

    我正在尝试做一个欧拉计划 http projecteuler net问题 我正在寻找 2 000 000 以下所有素数的总和 这就是我所拥有的 int main int argc char argv unsigned long int su
  • WcfSvcHost 的跨域异常

    对于另一个跨域问题 我深表歉意 我一整天都在与这个问题作斗争 现在已经到了沸腾的地步 我有一个 Silverlight 应用程序项目 SLApp1 一个用于托管 Silverlight SLApp1 Web 的 Web 项目和 WCF 项目
  • 结构体的内存大小不同?

    为什么第一种情况不是12 测试环境 最新版本的 gcc 和 clang 64 位 Linux struct desc int parts int nr sizeof desc Output 16 struct desc int parts
  • 两个类可以使用 C++ 互相查看吗?

    所以我有一个 A 类 我想在其中调用一些 B 类函数 所以我包括 b h 但是 在 B 类中 我想调用 A 类函数 如果我包含 a h 它最终会陷入无限循环 对吗 我能做什么呢 仅将成员函数声明放在头文件 h 中 并将成员函数定义放在实现文
  • 实例化类时重写虚拟方法

    我有一个带有一些虚函数的类 让我们假设这是其中之一 public class AClassWhatever protected virtual string DoAThingToAString string inputString retu
  • C 编程:带有数组的函数

    我正在尝试编写一个函数 该函数查找行为 4 列为 4 的二维数组中的最大值 其中二维数组填充有用户输入 我知道我的主要错误是函数中的数组 但我不确定它是什么 如果有人能够找到我出错的地方而不是编写新代码 我将不胜感激 除非我刚去南方 我的尝
  • 空指针与 int 等价

    Bjarne 在 C 编程语言 中写道 空指针与整数零不同 但 0 可以用作空指针的指针初始值设定项 这是否意味着 void voidPointer 0 int zero 0 int castPointer reinterpret cast
  • 如何在当前 Visual Studio 主机内的 Visual Studio 扩展中调试使用 Roslyn 编译的代码?

    我有一个 Visual Studio 扩展 它使用 Roslyn 获取当前打开的解决方案中的项目 编译它并从中运行方法 程序员可以修改该项目 我已从当前 VisualStudioWorkspace 成功编译了 Visual Studio 扩
  • 为什么使用小于 32 位的整数?

    我总是喜欢使用最小尺寸的变量 这样效果就很好 但是如果我使用短字节整数而不是整数 并且内存是 32 位字可寻址 这真的会给我带来好处吗 编译器是否会做一些事情来增强内存使用 对于局部变量 它可能没有多大意义 但是在具有数千甚至数百万项的结构
  • 为什么 isnormal() 说一个值是正常的,而实际上不是?

    include
  • 在 WPF 中使用 ReactiveUI 提供长时间运行命令反馈的正确方法

    我有一个 C WPF NET 4 5 应用程序 用户将用它来打开某些文件 然后 应用程序将经历很多动作 读取文件 通过许多插件和解析器传递它 这些文件可能相当大 gt 100MB 因此这可能需要一段时间 我想让用户了解 UI 中发生的情况
  • 相当于Linux中的导入库

    在 Windows C 中 当您想要链接 DLL 时 您必须提供导入库 但是在 GNU 构建系统中 当您想要链接 so 文件 相当于 dll 时 您就不需要链接 为什么是这样 是否有等效的 Windows 导入库 注意 我不会谈论在 Win
  • C++ 中的参考文献

    我偶尔会在 StackOverflow 上看到代码 询问一些涉及函数的重载歧义 例如 void foo int param 我的问题是 为什么会出现这种情况 或者更确切地说 你什么时候会有 对参考的参考 这与普通的旧参考有何不同 我从未在现
  • 类型或命名空间“MyNamespace”不存在等

    我有通常的类型或命名空间名称不存在错误 除了我引用了程序集 using 语句没有显示为不正确 并且我引用的类是公共的 事实上 我在不同的解决方案中引用并使用相同的程序集来执行相同的操作 并且效果很好 顺便说一句 这是VS2010 有人有什么
  • 如何确定 CultureInfo 实例是否支持拉丁字符

    是否可以确定是否CultureInfo http msdn microsoft com en us library system globalization cultureinfo aspx我正在使用的实例是否基于拉丁字符集 我相信你可以使

随机推荐

  • iPhone + 应用内购买测试

    我已经在现有应用程序之一中实现了应用程序内购买 我还创建了 SandBox 帐户来测试它 我已经运行了该应用程序并对其进行了测试 它运行完美 因为 我已经测试过了 通过购买该功能 就意味着我已经购买了该功能 现在 代码发生了变化 我想重新测
  • sqlalchemy 缓存一些查询

    我在一个实时网站上运行这个 当用户登录时 我查询他的个人资料以查看他有多少可用的 积分 积分是通过贝宝购买的 如果一个人购买积分并且付款成功 查询仍然显示 0 积分 即使我在 phpmyadmin 中运行相同的查询它会带来正确的结果 如果我
  • GZIP压缩级别对解压有影响吗

    据我了解 GZIP 是 LZ77 和 Huffman 编码的组合 可以配置 1 9 之间的级别 其中 1 表示最快的压缩 较少压缩 9 表示最慢的压缩方法 最佳压缩 我的问题是 级别的选择only影响压缩过程 或者根据用于压缩的级别 解压缩
  • 角度测试随机中断:“未捕获类型错误:您在预期流的位置提供了‘未定义’。”

    我们有一个中等大小的 Angular 应用程序 目前约有 700 个单元测试 几周前 完美的测试开始出现问题 更奇怪的是 运行测试两次可能会产生不同的结果 即不同的测试可能会失败 在控制台中 我们总是发现错误 未捕获的类型错误 您在需要流的
  • PHP,在类属性上调用静态方法

    我希望将对象存储为类的属性 然后我希望能够通过直接引用该属性来调用该类的静态方法 考虑以下 class myModel public static function all return 1 class myClass public mod
  • 无法在 Visual Studio 2022 上热重加载

    我将我的 Web 应用程序从 Visual Studio 2019 移至 2022 预览版 7 但我无法热重载 即使是很小的更改 例如更改 if a b to if a b 并且需要停止调试器 并且我不确定 COMPLUS ForceENC
  • 像音乐应用程序一样自定义 UISlider

    我构建了一个自定义滑块来显示音乐曲目播放的进度并允许在曲目内进行擦洗 两者都运行良好 但一旦停止拖动并且重新定位滑块 就会出现轻微的滞后 和跳跃的运动 Apple Music 应用程序滑块是无缝的 scrubberSlider Scrubb
  • 多维数组到 MVC 控制器

    我有以下控制器方法 public ActionResult Export string data string workbookName ExcelWorkbook workbook new ExcelWorkbook workbook A
  • 如果使用 Match_Constraints,嵌套约束布局不会显示

    我正在尝试在 Android 中创建一个嵌套的 ConstraintLayout 目标是在约束布局内左侧有一个图像 右侧有另一个约束布局 如下图所示 It correctly shows on the preview but inside
  • 在 Internet Explorer 中启用 SOCKS 4a/5

    出于匿名目的 我们希望使用不断变化的代理服务器 在搜索过程中 我们偶然发现了 TOR 项目 它非常适合正常浏览 但是我们还需要软件的代理 遗憾的是 这个第三方软件使用互联网浏览器作为基础 因此我们无法使用推荐的浏览器 更糟糕的是 IE 的代
  • bashrc if:表达式语法错误

    我编写了以下 bashrc bashrc Source global definitions if f etc bashrc then etc bashrc fi User specific aliases and functions fu
  • 更新了 SDK 版本,出现 ClassNotFoundException: android.support.v4.view.ViewPager

    当我在处理 Android 项目时 我发现 Logcat 很烦人 没有将滚动条保持在给定点 并了解到更新 SDK 版本会添加一个暂停按钮来解决此问题 我更新到 SDK 版本 17 现在遇到了一些以前没有的奇怪问题 我删除并添加了 andro
  • VB.Net:测试多个值是否相等?

    如何测试一行中多个值的相等性 基本上我想做 if val1 val2 val3 valN 但在 VB Net 中 If val1 valN AndAlso val2 valN AndAlso Then End If 当测试多个值时 这可能会
  • 如何在SD卡上创建私人文件夹

    我的应用程序用于安全目的 因此 从我的应用程序用户捕获的照片中 所有照片都存储在一个文件夹中 该文件夹不应从任何其他应用程序访问 并且当设备连接到计算机系统时不应授予访问权限 如果用户想查看这些图像 他应该只能从我的应用程序访问 根据这个g
  • 设置 UIView 的 self 背景颜色

    我正在尝试从自定义视图类的 m 内部执行此操作not从 XIB 加载 而是以编程方式加载 id initWithFrame CGRect frame self super initWithFrame frame if self Initia
  • 未找到 ${env.JAVA_HOME} - Ant

    在我的 build xml 文件中 我有以下几行
  • 在 MySQL 中正确实现超类型子类型

    下面是一个数据库图表 我试图在其中确定适当的设计 这里有一些注意事项 员工 经理与客户相关联 The partyid是一种在全球范围内代表一个人的方式 客户 员工 经理 需要一直向下传播吗 它应该是所有表中的主键还是仅代表个人的表中的主键
  • 无法解析方法 getMap()

    我试图让地图片段在我的应用程序中工作 但在尝试获取 GoogleMap 对象时仍然出现错误 FragmentWithMap java import android Manifest import android app Activity i
  • string::size_type 而不是 int

    const std string size type cols greeting size pad 2 2 Why string size type int应该可以工作 它包含数字 空头也能容纳数字 与签名字符一样 但这些类型都不能保证足够
  • 当委托构造函数抛出异常时,内存是否会自动回收?

    从此 当委托构造函数抛出异常时 析构函数是否被调用 https stackoverflow com q 17657761 14065 class X public X X int X throw std exception X double