C++ new_handler空间分配失败处理

简介:

C++ new_handler空间分配失败处理

 

动态分配空间、内存动态分配与回收对于任何一个程序员来说都尤为重要,特别是嵌入式C/C++程序员更为如此,malloc, remalloc, new等等,很有可能就申请空间失败,对申请失败的异常处理更是比较棘手。在C++中提倡使用new来代替malloc,因为new比malloc更加安全,更加效率。

 

很多程序员,包括我自己都喜欢性的使用这种C/C++代码来申请空间。

 

#include <iostream> #include <windows.h> using namespace std; typedef int Type; typedef struct _Node { Type data; struct _Node *next; }Node; int main(void) { Node *pNode = (Node *)(malloc(sizeof(Node))); if (!pNode) { abort(); } return 0; }

 

C++中,这里有问题吗?C程序员来说一般都会写类似的代码。

 

C++中,很多错误都会以异常的方式抛出,而且对于一个稍大的项目来说异常处理通常会设计专门的异常类去处理。

在《Effective C++》中则提到了一个比较智能的使用异常的方式去处理动态分配空间失败:

 

 

//这里先提到,详细的解释和代码在后面 new_handler; new_handler set_new_handler(new_handler p);

 

他们被定义在

#include <new> using namespace std;

 

 

new_handler和set_new_handler的申明如下:

 

//new_handler typedef void (×new_handler)(); //set_new_handler new_handler set_new_handler(new_handler p);

 

new_handler是一个参数为空的函数指针。

set_new_handler就是设置异常处理函数的入口,有程序员自己定义然后传入。

当空间分配失败之后,就会调用new_handler异常处理函数,然后才会抛出异常。也就是说异常的抛出是在调用new_handler之后。

 

对于一个动态内存分配失败的异常处理函数应该至少具有以下几个特点:

 

1.确保内存分配成功。

所谓确保内存分配成功,也就是说当new的时候不会失败。这是一个策略问题。我们可以在调用new之前,就申请一块较大的空间,当new空间的时候,就是放一点

 

2.设置不同的new_handler。

对于这一点,我们可以通过改变new_handler的参数以及申请空间的数量来做到。以确保下次申请空间成功。

 

3. 解除new_handler。

即传入NULL指针。

 

4.异常抛出。

 

那么。实际上,以上4点,set_new_handler已经可以做到了。

 

 

#include <iostream> #include <new> //new_handler,set_new_handler #include <windows.h> using namespace std; void NoMemory() { cout << "No adequate memory left" << endl; abort(); } int main(void) { set_new_handler(NoMemory); //这里实际很难碰到申请失败的情况 BYTE *pData = new BYTE[0x5fffffff]; return 0; }

 

 

实际上,如果new_handler中没有abort的话,new_handler会被循环的调用下去,直到申请空间成功为止。

 

 

目录
相关文章
|
1月前
|
存储 程序员 C++
C++堆内存分配
C++堆内存分配
28 2
|
1月前
|
C++ 容器
【C++】STL之空间配置器(了解)
【C++】STL之空间配置器(了解)
|
6天前
|
C++
C++一分钟之—名空间(namespace)的作用与使用
【6月更文挑战第22天】C++的命名空间是代码组织的关键,防止命名冲突并促进模块化。通过`namespace`定义代码块,如`MyNamespace{...}`,并使用别名(`namespace MN = MyNamespace::...`)简化引用。避免过度使用和嵌套,以及`using namespace`的滥用,而应在小范围内导入所需成员。明智选择名空间名称并有效利用`using`声明,能提升代码可读性和专业性。
9 1
|
8天前
|
C++
C++对C的改进和拓展\名字空间
C++对C的改进和拓展\名字空间
7 1
|
2天前
|
算法 C++ 容器
C++之vector容器操作(构造、赋值、扩容、插入、删除、交换、预留空间、遍历)
C++之vector容器操作(构造、赋值、扩容、插入、删除、交换、预留空间、遍历)
8 0
|
30天前
|
存储 算法 C语言
从C语言到C++_38(C++的IO流+空间适配器)STL六大组件联系(下)
从C语言到C++_38(C++的IO流+空间适配器)STL六大组件联系
29 5
|
8天前
|
C++
C++对C的改进和拓展\动态内存空间管理
C++对C的改进和拓展\动态内存空间管理
8 0
|
14天前
|
存储 IDE 编译器
c++primer plus 6 读书笔记 第九章 内存模型和名称空间
c++primer plus 6 读书笔记 第九章 内存模型和名称空间
|
30天前
|
算法 C语言 C++
从C语言到C++_38(C++的IO流+空间适配器)STL六大组件联系(上)
从C语言到C++_38(C++的IO流+空间适配器)STL六大组件联系
26 0
|
1月前
|
存储 Linux 程序员
【Linux C/C++ 堆内存分布】深入理解Linux进程的堆空间管理
【Linux C/C++ 堆内存分布】深入理解Linux进程的堆空间管理
166 0