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会被循环的调用下去,直到申请空间成功为止。

 

 

时间: 2024-09-11 16:01:59

C++ new_handler空间分配失败处理的相关文章

PROC++批量导入导出ORACLE数据库表

oracle|数据|数据库 最近在开发一个项目中,为了解决数据库IO瓶颈,不得不把数据库中的数据导出为文本文件.文本传到客户端后又要导入到数据库.本人用C++Builder嵌入PROC++写了一个导入导出的DLL.如果对你有用深感荣幸!详细内容如下:   一.准备工作 计算机环境:Win 2000 PRO,ORACLE 9i,C++ Builder 5.5 引入必要的ORACLE内部函数:要用的函数在$(ORACEL_HOME)\bin qlora9.dll链接库中.为了能在C++ Builde

数据结构C语言实现之线性表

#include <stdio.h>#include <stdlib.h>typedef int elemType; /************************************************************************//* 以下是关于线性表顺序存储操作的16种算法 *//************************************************************************/struct Lis

数据结构C语言实现之队列

#include <stdio.h>#include <stdlib.h> typedef int elemType;/************************************************************************//* 以下是关于队列链接存储操作的6种算法 *//************************************************************************/struct sNode

code blocks-malloc函数出现段错误可能是哪些原因引起的?

问题描述 malloc函数出现段错误可能是哪些原因引起的? 如题,code block环境下,代码运行了一段时间后在某处进行malloc()函数返回了段错误.请问malloc函数出现段错误可能是哪些原因引起的? 解决方案 没有足够内存分配,或者malloc参数错误. 解决方案二: 段错误也可能是指针无效. 解决方案三: malloc 分配内存非法,后者分配出错 解决方案四: 程序有内存泄漏 导致新空间分配失败 malloc的内存不需要的时候要free 解决方案五: malloc 没有足够的内存分

c语言-反转单向链表,C语言,运行出错

问题描述 反转单向链表,C语言,运行出错 #include #include /* run this program using the console pauser or add your own getch, system("pause") or input loop */ typedef struct LNode{ int node; struct LNode *next; } LNode,*LinkList; LinkList Head_Node() { LinkList he

对象池加速游戏内存分配的解决方案

相比内存池,对象池更易用更容易管理,而且还可以利用脏数据,也就是上次被回收掉的对象的数据.而且偶尔的空间分配失败其实不是那么重要(后面会讲怎么在会失败的情况下完成分配任务),游戏中还是速度更重要些. 原理 一次申请大量连续内存(整数个对象大小),最好用堆,当然如果用栈数组也没人拦你,栈空间可是相当有限- 由于分配的对象生存期是不固定的(如下图),池不可能保持已分配对象的连续性,这时进行块移动会降低程序效率.   分配       分配 分配   分配   所以需要把闲置对象的指针放入容器中来管理

小米随身wifi驱动安装失败解决方法

  小米随身wifi支持windows xp, windows vista 32/64位,windows 7 32/64位 ,windows 8 32/64位usb 2.0接口;符合ieee 802.11n协议,兼容ieee 802.11g和ieee 802.11b标准; 下面,我们就来看看小米随身wifi驱动无法安装的解决方法. 米随身wifi驱动安装失败解决方法: 1.下载最新版本的小米随身wifi驱动,重新安装后,换个usb口重新连接小米随身wifi可以了. 2.安装时,用系统默认的就路径

access-网站后太上传相片失败.打开网站出现如下问题

问题描述 网站后太上传相片失败.打开网站出现如下问题 Microsoft OLE DB Provider for ODBC Drivers 错误 '80004005' [Microsoft][ODBC Microsoft Access 驱动程序] 不能使用 '(未知的)':文件已在使用中. /index.asp,行 5 解决方案 文件被占用,看看数据库访问后是不是没有关闭. 解决方案二: 第一次接触这个 什么都不会搞啊

SQL Server 2008安装的时提示“重启计算机失败”怎么办?

详细出错信息如下: RebootRequiredCheck 检查是否需要挂起计算机重新启动.挂起重新启动会导致安装程序失败. 失败 需要重新启动计算机.必须重新启动计算机才能安装 SQL Server 出问题后我在网上找的解决方法如下: a .重启机器,再进行安装,如果发现还有该错误,请按下面步骤b.在开始->运行中输入regeditc.到HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\d.在右边窗口右击Pe