C++中nothrow的介绍及使用

2023-11-15

在C中,使用malloc等分配内存的函数时,一定要检查其返回值是否为”空指针”,并以此作为检查内存操作是否成功的依据,这种Test-for-NULL代码形式是一种良好的编程习惯,也是编写可靠程序所必需的。

在C++中new在申请内存失败时默认会抛出一个std::bad_alloc 异常。如果出现这个异常,那就意味着内存耗尽,或者有其它原因导致内存分配失败。所以,按照C++标准,如果想检查new是否成功,则应该通过try catch捕捉异常。但有些编译器不支持try catch。C++标准化委员会不想遗弃这些Test-for-NULL的代码,所以他们提供了operator new的另一种可选形式---- nothrow,用以提供传统的Failure-yields-NULL行为。

当使用new申请一块内存失败时,抛出异常std::bad_alloc是C++标准中规定的标准行为,所以使用try { p = new int[size];} catch(std::bad_alloc) { … } 的处理方式。

struct nothrow_t {
	// placement new tag type to suppress exceptions
};

extern const nothrow_t nothrow; // constant for placement new tag

其中,nothrow_t通常是一个空结构,其唯一目的是提供编译器一个可根据重载规则识别具体调用的类型。用户一般简单地使用"new(std::nothrow) 类型"(nothrow是一个nothrow_t类型的常量)来调用这个placement new操作符。它与标准new的区别是,new在分配内存失败时会抛出异常,而"new(std::nothrow)"在分配内存失败时会返回一个空指针。

new operator分配内存失败后,缺省的行为不是返回NULL,而是抛出异常std::bad_alloc。所以判断返回值是否为NULL没有任何意义。

  std::nothrow: This constant value is used as an argument for operator new and operator new[] to indicate that these functions shall not throw an exception on failure, but return a null pointer instead.

By default, when the new operator is used to attempt to allocate memory and the handling function is unable to do so, a bad_alloc exception is thrown. But when nothrow is used as argument for new, it returns a null pointer instead.

This constant (nothrow) is just a value of type nothrow_t, with the only purpose of triggering an overloaded version of the function operator new (or operatornew[]) that takes an argument of this type.

以下是测试代码:

#include "nothrow.hpp"
#include <iostream>
#include <new> // std::nothrow

// reference: http://www.cplusplus.com/reference/new/nothrow/
int test_nothrow1()
{
	std::cout << "Attempting to allocate 1 MiB...";
	char* p = new (std::nothrow) char[1048576];
	if (p == 0)
		std::cout << "Failed!\n";
	else {
		std::cout << "Succeeded!\n";
		delete[] p;
	}

	return 0;
}

// reference: http://en.cppreference.com/w/cpp/memory/new/nothrow
int test_nothrow2()
{
	try {
		while (true) {
			new int[100000000ul];   // throwing overload
		}
	}
	catch (const std::bad_alloc& e) {
		std::cout << e.what() << '\n';
	}

	while (true) {
		int* p = new(std::nothrow) int[100000000ul]; // non-throwing overload
		if (p == nullptr) {
			std::cout << "Allocation returned nullptr\n";
			break;
		}
	}

	return 0;
}
GitHubhttps://github.com/fengbingchun/Messy_Test

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

C++中nothrow的介绍及使用 的相关文章

  • C++11中std::condition_variable的使用

  • C++中的虚函数表介绍

    在C 语言中 当我们使用基类的引用或指针调用一个虚成员函数时会执行动态绑定 因为我们直到运行时才能知道到底调用了哪个版本的虚函数 所以所有虚函数都必须有定义 通常情况下 如果我们不使用某个函数 则无须为该函数提供定义 但是我们必须为每一个虚
  • C++11中模板类std::enable_shared_from_this的使用

    C 11中的模板类template
  • C和C++安全编码笔记:动态内存管理

    4 1 C内存管理 C标准内存管理函数 1 malloc size t size 分配size个字节 并返回一个指向分配的内存的指针 分配的内存未被初始化为一个已知值 2 aligned alloc size t alignment siz
  • C++中namespace detail或namespace internal的使用

    在很多开源代码中偶尔会使用名字为 detail 或 internal 的命名空间 如OpenCV的modules目录中 有些文件中使用了namespace detail 有些文件中使用了namespace internal 名为detail
  • C和C++安全编码笔记:指针诡计

    指针诡计 pointer subterfuge 是通过修改指针值来利用程序漏洞的方法的统称 可以通过覆盖函数指针将程序的控制权转移到攻击者提供的外壳代码 shellcode 当程序通过函数指针执行一个函数调用时 攻击者提供的代码将会取代原本
  • log库spdlog简介及使用

    spdlog是一个开源的 快速的 仅有头文件的C 11 日志库 code地址在 https github com gabime spdlog 目前最新的发布版本为0 14 0 它提供了向流 标准输出 文件 系统日志 调试器等目标输出日志的能
  • 提高C++性能的编程技术笔记:多线程内存池+测试代码

    为了使多个线程并发地分配和释放内存 必须在分配器方法中添加互斥锁 全局内存管理器 通过new 和delete 实现 是通用的 因此它的开销也非常大 因为单线程内存管理器要比多线程内存管理器快的多 所以如果要分配的大多数内存块限于单线程中使用
  • C和C++安全编码笔记:并发

    并发是一种系统属性 它是指系统中几个计算同时执行 并可能彼此交互 一个并发程序通常使用顺序线程和 或 进程的一些组合来执行计算 其中每个线程和进程执行可以在逻辑上并行执行的计算 这些进程和 或 线程可以在单处理器系统上使用分时抢占式的方式
  • OpenCV代码提取:遍历指定目录下指定文件的实现

    OpenCV 3 1之前的版本 在contrib目录下有提供遍历文件的函数 用起来比较方便 但是在最新的OpenCV 3 1版本给去除掉了 为了以后使用方便 这里将OpenCV 2 4 9中相关的函数给提取了出来 适合在Windows 64
  • 提高C++性能的编程技术笔记:引用计数+测试代码

    引用计数 reference counting 基本思想是将销毁对象的职责从客户端代码转移到对象本身 对象跟踪记录自身当前被引用的数目 在引用计数达到零时自行销毁 换句话说 对象不再被使用时自行销毁 引用计数和执行速度之间的关系是与上下文紧
  • C++11中std::bind的使用

    std bind函数是用来绑定函数调用的某些参数的 std bind它可以预先把指定可调用实体的某些参数绑定到已有的变量 产生一个新的可调用实体 它绑定的参数的个数不受限制 绑定的具体哪些参数也不受限制 由用户指定 std bind 1 将
  • C++中vector的使用

    向量std vector是一种对象实体 能够容纳许多各种类型相同的元素 包括用户自定义的类 因此又被称为序列容器 与string相同 vector同属于STL Standard Template Library 中的一种自定义的数据类型 可
  • C++中的封装、继承、多态

    封装 encapsulation 就是将抽象得到的数据和行为 或功能 相结合 形成一个有机的整体 也就是将数据与操作数据的源代码进行有机的结合 形成 类 其中数据和函数都是类的成员 封装的目的是增强安全性和简化编程 使用者不必了解具体的实现
  • C++中typeid的使用

    RTTI Run TimeType Information 运行时类型信息 它提供了运行时确定对象类型的方法 在C 中 为了支持RTTI提供了两个操作符 dynamic cast和typeid The typeid operator pro
  • CSV文件简介及C++实现

    逗号分隔值 Comma Separated Values CSV 有时也称为字符分隔值 因为分隔字符也可以不是逗号 其文件以纯文本形式存储表格数据 数字和文本 纯文本意味着该文件是一个字符序列 不含必须象二进制数字那样被解读的数据 CSV文
  • 程序员的自我修养--链接、装载与库笔记:目标文件里有什么

    编译器编译源代码后生成的文件叫做目标文件 目标文件从结构上讲 它是已经编译后的可执行文件格式 只是还没有经过链接的过程 其中可能有些符号或有些地址还没有被调整 其实它本身就是按照可执行文件格式存储的 只是跟真正的可执行文件在结构上稍有不同
  • 概率论中伯努利分布(bernoulli distribution)介绍及C++11中std::bernoulli_distribution的使用

    Bernoulli分布 Bernoulli distribution 是单个二值随机变量的分布 它由单个参数 0 1 给出了随机变量等于1的概率 它具有如下的一些性质 P x 1 P x 0 1 P x x x 1 1 x Ex x Var
  • C++14中binary literals的使用

    一个形如42的值被称作字面值常量 literal 这样的值一望而知 每个字面值常量都对应一种数据类型 字面值常量的形式和值决定了它的数据类型 我们可以将整型字面值写作十进制 基数为10 八进制 基数为8 或十六进制 基数为16 数的形式 以
  • Linux下getopt函数的使用

    getopt为解析命令行参数函数 它是Linux C库函数 使用此函数需要包含系统头文件unistd h getopt函数声明如下 int getopt int argc char const argv const char optstri

随机推荐

  • 数据结构习题解析与实验指导-严蔚敏数据结构-第二章:线性表(刷题记录)

    目录 第二章 线性表 刷题记录 P 18 20 第一题 2022年4月7日 星期四 凌晨00 28 01 12 第二题 2022年4月7日 星期四 凌晨10 01 10 21 第三题 2022年4月7日 星期四 晚上23 21 23 31
  • 使用Docker-容器命令案例2

    案例 进入容器 修改文件 需求 进入Nginx容器 修改HTML文件内容 添加 传智教育欢迎您 提示 进入容器要用到docker exec命令 步骤 1 进入容器 进入我们刚刚创建的nginx容器的命令为 docker exec it mn
  • 最短路径——Dijkstra算法(C语言实现)

    最短路径 Dijkstra算法 基本概念 1 最短路径 非带权图 边数最少的路径 带权图 边上的权值之和最少的路径 基本思想 1 v 源点 S 已经生成最短路径的终点 w
  • Redis常用的五种数据类型

    Redis常用的五种数据类型 String Key Value String是最常用的一种数据类型 普通的key value存储都可以归为此类 一个Key对应一个Value string类型是二进制安全的 Redis的string可以包含任
  • 使用xshell6连接Linux服务器失败的原因

    1 我在使用xshell6连接到服务器上面发生了连接失败的问题 2 仔细分析了一下 可能存在的原因有 在虚拟机上没有连上网 所以首先要保证要连接上网 没有开启SSHD服务可以通过系统 gt 服务来查看是否启动了该服务 可以在命令行中输入se
  • 如何用python进行数据分析

    文章目录 前言 1 Python数据分析流程及学习路径 2 利用Python读写数据 3 利用Python处理和计算数据 4 利用Python分析建模 5 利用Python数据可视化 零基础Python学习资源介绍 Python学习路线汇总
  • DNS 预解析是什么?怎么实现?

    DNS优化 在介绍dns prefetch之前 先要提下当前对于DNS优化主流方法 一般来说 一次DNS解析需要耗费 20 120ms 所以为了优化DNS 我们可以考虑两个方向 减少DNS请求次数 缩短DNS解析时间dns prefetch
  • 网站服务器 80端口吗,你的服务器打开IIS80端口了吗?

    我是中国药都网的站长 做门户网站有二年了 也在A5上和大家分享了很多地方门户经验 今天继续在A5这个平台跟大家分享经验 这个网站我是从2009年做的 用了3次服务器 但是只有第三次用服务器打开了iis80端口并看到意向不到的效果 下面给大家
  • GEE学习笔记 五十五:GEE编辑器绘制样本点的一个bug(官方在5.1给出反馈已经修复相关bug)

    提交的Bug官方在5月1日已经给出反馈 测试发现已经修复了这个Bug 注释 这个是今天发现的一个bug 官方后续肯定会修复的 在做地物分类的时候我们会采用GEE在线采集样本方式 但是这个有一个问题需要注意 如果直接使用绘制矩形和点会将点变为
  • unity3D 下雨效果实现

    这个效果借鉴自unity例子angrybot 并做了一部分适应项目的修改 angrybot的实现方法 单个雨滴 RainBox 1 Start的时候从Mgr里面取一个雨滴的mesh给MeshFilter使用 2 在Update 做下落的循环
  • uniapp-历史搜索记录

    应用场景 很多搜索场景内都能用到这个功能 大概就是用户搜索了某个关键字 然后搜索的关键字可以持久的保存下来 下次打开搜索的时候可以达到快速点击搜索的效果 实现步骤 1 先给输入框双向绑定数据和事件
  • 生成式人工智能的潜在有害影响与未来之路(一)

    这是本文的第1版 反映了截至2023年5月15日 Generative AI的已记载的和预期的危害 由于Generative AI的发展 使用和危害的快速变化 我们承认这是一篇内在的动态论文 未来会发生变化 在本文中 我们使用一种标准格式来
  • 【观察】VMware:二十而冠,以梦为马不负韶华

    申耀的科技观察 读懂科技 赢取未来 今年7月 VMware首席执行官Pat Gelsinger成功登顶了世界七大高峰之一的乞力马扎罗山 期间的巨大挑战可想而知 但越困难越危险 也就越迷人 因为登顶的魅力 也是挑战自我 超越自我的过程 这似乎
  • idea添加自定义注释

    idea添加自定义注释 废话不多说 直接上图 1 设置Settings gt 编辑器Editor gt Live Templates 2 右侧加号 3 填写快捷缩写Abbreviation 描述Description 4 填写注释的内容 5
  • Nginx日志按日分割方法

    本文使用logrotate工具对Nginx日志进行按日的自动切割 操作系统为Centos7 6 步骤如下 1 编写针对Nginx的logrotate脚本如下 保存在 etc logrotate d usr local nginx logs
  • 数据结构——拓扑排序算法

    拓扑排序的深度优先算法 Topological Sort with Depth First Search 是一种在有向无环图 DAG 中进行排序的方法 该算法使用递归来进行深度优先搜索 并在搜索完成后将节点添加到排序结果中 include
  • Set接口概述

    1 Set集合和List集合的区别 Set 不允许元素重复 集合元素唯一 元素可以为null 不能保证迭代顺序恒久不变 无序 存储和取出不一致 List 允许元素重复 并且元素有序 存储和取出一致 2 Set 集合存储元素时可以保证元素的唯
  • 计算机毕业设计 基于SSM框架+Vue的企业人事信息管理系统的设计与实现 Java实战项目 附源码+文档+视频讲解

    博主介绍 从事软件开发10年之余 专注于Java技术领域 Python人工智能及数据挖掘 小程序项目开发和Android项目开发等 CSDN 掘金 华为云 InfoQ 阿里云等平台优质作者 文末获取源码联系 精彩专栏推荐订阅 不然下次找不到
  • idea中配置Tomcat找不到的解决办法

    idea中配置Tomcat找不到的解决办法 最近重装了系统 所以重新下载了一下idea 配置tomcat时发现找不到Tomcat Server 下面是一种解决方法 希望也可以帮助到大家 具体的实施步骤 File gt Settings gt
  • C++中nothrow的介绍及使用

    在C中 使用malloc等分配内存的函数时 一定要检查其返回值是否为 空指针 并以此作为检查内存操作是否成功的依据 这种Test for NULL代码形式是一种良好的编程习惯 也是编写可靠程序所必需的 在C 中new在申请内存失败时默认会抛