本文转载自:http://www.51testing.com/html/70/n-827070-2.html

在C++语言中,我们经常会使用new给一个对象分配内存空间,而当内存不够会出现内存不足的情况。C++提供了两种报告方式:

  1、抛出bad_alloc异常来报告分配失败;

  2、返回空指针,而不会抛出异常。

  C++为什么会采用这两种方式呢?这主要是由于各大编译器公司设计C++编译器公司的结果,因为标准C++是提供了异常机制的。例如,VC++6.0中当new分配内存失败时会返回空指针,而不会抛出异常。而gcc的编译器对于C++标准支持比较好,所以当new分配内存失败时会抛出异常。

  究竟为什么会出现这种情况呢?

  首先,C++是在C语言的基础之上发展而来,而且C++发明时是想尽可能的与C语言兼容。而C语言是一种没有异常机制的语言,所以C++应该会提供一种没有异常机制的new分配内存失败报告机制;(确实是如此,早期的C++还没有加入异常机制)

  其次在返回空指针的实现过程中,C++采用的是malloc/calloc 等分配内存的函数,该类函数不会抛出异常,但是在分配内存失败时会返回“空指针”。

  最后,对于标准的C++,有着比较完善的异常处理机制,所以对于出现异常时,会抛出响应的异常。对于new分配失败时,系统会抛出bad_alloc异常。

  鉴于以上原因,我们在不同的编译器需要new分配失败时做不同的处理。例如:

情况1:

int* p = new int(5);
if ( p == 0 ) // 检查 p 是否空指针return -1;
...

情况2:

try {int* p = new int(5);// 其它代码
} catch ( const bad_alloc& e ) {return -1;
}

情况1和情况2的代码都是对于new失败时的处理,而针对不同的编译器,可以这种处理会完全失效。如果在gcc编译器采用情况1,那么if(p==0)完全是没有意义的,因为不管new内存分配成功失败与否,都不会出现p=0的情况。即,如果分配成功,p=0完全不可能;而分配失败,new会抛出异常跳过其后面的代码。而需要采用情况2的处理方式,即应该来捕捉异常。

  同样,如果在VC++6.0中采用情况2的代码,那么new分配失败时,完全不会抛出异常,那么捕捉异常也是徒劳的。

  所以在new分配内存的异常处理时要特别小心,可以两种方式联合使用,来解决跨平台跨编译器的难题。

  当然情况2中的异常处理代码是最简单的处理方式,下面我们为其制定一个客户制定的错误处理函数,即new-handler。

typedef void (*new_handler)();
new_handler set_new_handler(new_handler p) throw();

这里首先定义new-handler函数指针类型,然后定义一个new-handler函数set_new_handler,其参数是指向operator new无法分配足够内存时应该被调用的函数。其返回指也是一个指针,指向set_new_handler被调用前正在执行(但是马上就要被替换)的那个new-handler函数。下面设计一个当operator new无法分配足够内存时应该被调用的函数:

void noMemoryToAlloc()
{std::cerr << "unable to satisfy request for memory\n";std::abort();
}

使用noMemoryToAlloc函数的代码为:

int main()
{set_new_handler(nomorememory);int *pArray = new int[100000000000000L];...}

当operator new无法分配足够空间时,noMemoryToAlloc就会被调用,于是程序就会发出一个错误信息cerr之后,调用abort函数结束程序。

  如果operator new无法分配足够空间时,我们希望不断调用new-handler函数,直到找到足够内存为止,那么我们的operator new函数就可以设计为:

void *operator new(std::size_t size) throw(std::bad_alloc)
{if ( size==0 ) {size  = 1;}while (true) {调用malloc等内存分配函数来尝试分配size大小的内存;if ( 分配成功 )return 指向分配得来的内存指针;new_handler globalHandler  = set_new_handler(0);set_new_handle(globalHandler);if(globalHandler)(*globalHandler)();elsethrow std::bad_alloc();}
}

采用new分配内存失败时为什么会出现两种错误报告方式?相关推荐

  1. malloc函数分配内存失败的原因及解决方法

    原文链接:http://blog.csdn.net/lighthear/article/details/70146602 malloc函数分配内存失败的原因及解决方法 先说结论 malloc()函数分 ...

  2. office打开服务器文件提示内存不足,Excel2016打开文档时提示内存或磁盘空间不足的两种解决方法...

    有时候,在Excel2016或者Excel2013中打开新建的空白文档提示:内存或磁盘空间不足,Microsoft Excel无法再次打开或保存任何文档.要想获得更多的可用内存,请关闭不再使用的工作簿 ...

  3. 服务器芯片市场容量,未来内存接口芯片市场规模 使用内存接口芯片的服务器内存模组主要有寄存内存模组(RDIMM)和减载内存模组(LRDIMM)两种。RDIMM需要一颗寄... - 雪球...

    来源:雪球App,作者: 炒股基本靠蒙,(https://xueqiu.com/9446807039/129589023) 使用内存接口芯片的服务器内存模组主要有寄存内存模组(RDIMM)和减载内存模 ...

  4. android 毫秒 计时器,Android时分秒计时器的两种实现方法

    可能我们在开发中会时常用到计时器这玩意儿,比如在录像的时候,我们可能需要在右上角显示一个计时器.这个东西其实实现起来非常简单. 只需要用一个控件Chronometer,是的,就这么简单,我都不好意思讲 ...

  5. 硬盘在计算机上没显示内存不足,打开Excel2016提示内存或磁盘空间不足的两种解决方法...

    在Excel2016或者Excel2013中打开新建的空白文档提示:内存或磁盘空间不足,Microsoft Excel无法再次打开或保存任何文档. 要想获得更多的可用内存,请关闭不再使用的工作簿或程序 ...

  6. oracle enlisttransaction,WAS运行时抛出的两种异常,经过google找到解决方案,记录以备案...

    在第一次运行范例时,您可能会得到以下错误: WSRdbDataSour I DSRA8203I: Database product name : Oracle WSRdbDataSour I DSRA ...

  7. iOS:图片上传时两种图片压缩方式的比较

    上传图片不全面的想法:把图片保存到本地,然后把图片的路径上传到服务器,最后又由服务器把路径返回,这种方式不具有扩展性,如果用户换了手机,那么新手机的沙盒中就没有服务器返回的图片路径了,此时就无法获取之 ...

  8. 0324的学习笔记----里面最重要的就是一个tom猫的动画,和涉及到的内存问题(创建imageview的两种方式,imagenamed就会形成缓存,占用很多内

    还是可以自己对着视频,或者自己有空的时候在做一遍,把按钮做全面的,比较有意思. 看视频的时间是:2015.11.2日上午. 0324: 01-作业-QQ登陆界面 (1) 键盘的退出:[self.vie ...

  9. [Win+Python]使用python接口测试时302重定向的两种处理方法

    目录 前言 1 接口简介 2 代码实现 2.1 自动重定向 2.2 跟随重定向 前言 我将在本文中简单介绍使用python进行接口测试时,遇到302重定向时的一些测试心得. 本文涉及实例中的一些关键信 ...

  10. bitdock系统错误_BitDock开机启动失败怎么办?给你两种解决方法

    最近很多BitDock的用户反映电脑开机的时候,BitDock老是启动失败.出现这样的情况,也尝试过手动将BitDock启动,可是都以失败告终,搞得电脑桌面的快捷方式又恢复到原来杂乱无章的模样了.那么 ...

最新文章

  1. WIN2000 Apache php mysql 安装及安全手册
  2. GDCM:gdcm::UUIDGenerator的测试程序
  3. 搭建nagios监控服务
  4. Drools 7.4.1.Final参考手册(六) 用户手册
  5. 小学计算机技术指导纲要,《中小学信息技术课程指导纲要(试行)》
  6. 剑与轮回找回服务器,剑与轮回自由之都1服开服时间表_剑与轮回新区开服预告_第一手游网手游开服表...
  7. 自己写的_top、_parent以及对iframe和frameset的理解
  8. 英国汇丰银行拒绝为客户处理加密货币交易
  9. 支持SMTP邮箱介绍
  10. ps怎么缩放图层大小_Photoshop如何调整图层大小?PS调整图层大小快捷键
  11. HTML5课题意义,毕业论文选题的意义万能套话
  12. verilog编程,可能你一直在错误地使用计数器cnt
  13. 41-牛栏-最短路径
  14. codeforce Zebras(思维 + 模拟)
  15. 南阳理工acm71 独木舟上的旅行(贪心简单题)
  16. MEM/MBA英语基础(10)非谓语动词
  17. Linux权限drwxrwxrwx是什么意思?
  18. python中矩阵的表示方法,稀疏矩阵在Python中的表示方法
  19. mysql 错误码: 1267
  20. A. Frog Jumping

热门文章

  1. nginx访问日志配置及访问日志切割实战
  2. mysql备份工具命令xtra_mysql xtrabackup备份工具使用
  3. 127.0.0.1 zxt.php_windows 10 下docker布置nginx+php环境,用宿主WEB目录负载均衡
  4. python opencv 中文路径_解决python cv2.imread 读取中文路径的图片返回为None的问题
  5. spring boot antd pro 跨域_springboot配置跨域
  6. python按照日期筛选excel_用python判断Excel单元格格式为输出日期(日期字段位置不固定)的,按datetime格式输出日期(而非float)_python excle 日期列...
  7. java泛化_java 类字面常量,泛化的Class引用
  8. java interface泛型_JAVA的接口泛型
  9. 基础连接已关闭解决办法_解决|罗技蓝牙键盘连接ipad后打不出字?
  10. python bt下载_【图片】分享一段功能非常简陋的python代码实现下载free种【pt吧】_百度贴吧...