c++ new失败后做了什么?

一直以来我都在写着这样的代码

char* buf = new char[1024];
if(NULL == buf){
printf("new failure\n");
}

可new失败以后真的会返回NULL吗?写了个例子测试一下:


#include <stdlib.h>
#include <stdio.h>

#define BUF_SIZE (100*1024*1024)

int main(int argc,char** argv){
int i = 0;
for(;i < 100;++i){
char* buf = NULL;
//buf = (char*)malloc(BUF_SIZE);
buf = new char[BUF_SIZE];
if(NULL != buf){
printf("malloc success i = %d\n",i);
}
else{
printf("malloc fail i = %d\n",i);
}
}
return 0;
}

编译一下:$ g++ main.cpp -o new ,然后执行,结果如下:

前29次new都执行成功了,在第30次程序并没有输出“malloc fail”,而是dump了。

在来看一下c中最常用的的malloc,在失败时返回什么,修改一下以上代码,编译执行,结果如下:

输出结果和我们预期一样,看一下malloc的man手册,果然是失败时返回NULL。


RETURN VALUE
For calloc() and malloc(), the value returned is a pointer to the allo-
cated memory, which is suitably aligned for any kind of variable, or
NULL if the request fails.

其实,c++中当new不能分配足够的内存时,默认动作是抛出bad_alloc异常,因此,修改代码如下:


#include <stdlib.h>
#include <stdio.h>

#define BUF_SIZE (100*1024*1024)

int main(int argc,char** argv){
int i = 0;
for(;i < 100;++i){
char* buf = NULL;
//buf = (char*)malloc(BUF_SIZE);
try{
buf = new char[BUF_SIZE];
}catch(...){
printf("malloc fail i = %d\n",i);
continue;
}
{
printf("malloc success i = %d\n",i);
}
}
return 0;
}

编译执行后,结果同上。

由于new这种默认的特性,当我们的程序负载很高时,如果动态的分配堆内存,很容易照成程序dump,常见的一些做法可以在程序启动之初便将所需的内存预先分配出来,避免在程序运行时动态的分配内存;或者也可以使用set_new_handler函数处理new失败后的情况。更多new
和delete的行为可以参考《effective c++》第8章。

很多时候我们都在理所当然的写程序,而问题往往就出现在这些“理所当然”的地方,我待code如初恋,code虐你千百遍,爱它就去请深入了解它,否则它真的会虐死你。

[完]    2014-6-4 17:36:17 by:TMDJoJo

c++ new失败后做了什么?

时间: 2024-10-12 19:06:02

c++ new失败后做了什么?的相关文章

删除Windows中隐藏的物理网卡和网络虚拟化失败后的虚拟网卡

Windows环境下,在更换硬件服务器主板和网卡等硬件.恢复操作系统或者网络虚拟化失败后,可能会出现网卡方面的问题.例如,设备管理器中多了不应该存在的网卡:因命名冲突无法重命名当前网络连接:IP地址冲突却找不到那个与之冲突的网卡:网络虚拟化失败后出现无法删除的虚拟网卡等等.下面我们就来总结一下如何删除这些可见或不可见的Ghost一样的网卡. 一.识别各类网络设备和网络连接 由于网络虚拟化会在物理机上新增许多虚拟网络设备(包括虚拟网卡),情况会变得复杂,因而首先我们需要分清他们.当然如果没有进行网

Oracle 数据库 JOB 失败后的重试规律解密

由于官方文档上没有找到相关的说明,所以这里进行了如下测试,为了找到oracle数据库中 job 失败后重试时间的规律. 数据库版本:11.2.0.3 测试说明:这里创建了一个日志表以及一个运行时必定出错的procedure,用于job的运行.这里只要记录下每次job执行时视图user_jobs 中的 next_date就可以推断出job 执行失败后的重试规律. 为了测试job的重试规律我做了如下工作 日志表以及序列: create table job_exec_logs (id number ,

【web开发】★☆之基于Map实现(用户登录三次失败后)24小时之内限制登录!

[web开发]★☆之基于Map实现(用户登录三次失败后)24小时之内限制登录! 近期在改一个老项目(struts1做的),客户现在想实现如下效果,用户在登录失败三次之后,锁定用户,需要信息部管理人员进行解锁!我第一想法,是在其数据库User表中加一个字段,记录登录失败的次数,但是数据库添加字段需要远程操作数据库,而对方的数据库又被各种加密软件包围!不是很方便,所以想了一下解决方案,利用Map来进行处理! 首先说一个思路,新建实体类,只有两个属性,登录失败次数,登录时间,实现get,set方法!

new内存失败后的正确处理(转)

本文摘录自建议30:new内存失败后的正确处理. 应该有很多的程序员对比尔盖茨的这句话有所耳闻: 对于任何一个人而言,640KB应当是足够的了.(640K ought to be enough for everybody.) 不幸的是,伟大的比尔盖茨也失言了.随着硬件水平的发展,内存变得越来越大,但是似乎仍不能满足人们对内存日益增长的需求.所以呢,我们C/C++程序员在写程序时也必须考虑一下内存申请失败时的处理方式. 通常,我们在使用new进行内存分配的时候,会采用以下的处理方式: 1 char

Spring Cloud Stream消费失败后的处理策略(三):使用DLQ队列(RabbitMQ)

应用场景 前两天我们已经介绍了两种Spring Cloud Stream对消息失败的处理策略: 自动重试:对于一些因环境原因(如:网络抖动等不稳定因素)引发的问题可以起到比较好的作用,提高消息处理的成功率. 自定义错误处理逻辑:如果业务上,消息处理失败之后有明确的降级逻辑可以弥补的,可以采用这种方式,但是2.0.x版本有Bug,2.1.x版本修复. 那么如果代码本身存在逻辑错误,无论重试多少次都不可能成功,也没有具体的降级业务逻辑,之前在深入思考中讨论过,可以通过日志,或者降级逻辑记录的方式把错

聊聊数据库乐观锁和悲观锁,乐观锁失败后重试

在写入数据库的时候需要有锁,比如同时写入数据库的时候会出现丢数据,那么就需要锁机制. 数据锁分为乐观锁和悲观锁,那么它们使用的场景如下: 1. 乐观锁适用于写少读多的情景,因为这种乐观锁相当于JAVA的CAS,所以多条数据同时过来的时候,不用等待,可以立即进行返回. 2. 悲观锁适用于写多读少的情景,这种情况也相当于JAVA的synchronized,reentrantLock等,大量数据过来的时候,只有一条数据可以被写入,其他的数据需要等待.执行完成后下一条数据可以继续. 他们实现的方式上有所

MAC OS X 10.10 应用程序下载失败后lunchpad产生灰色图标的解决办法

方法如下:打开应用程序- 实用工具 - 终端. 以此出入如下字符 defaults write com.apple.dock ResetLaunchPad -bool true killall Dock 再次打开 LaunchPad 的时候, 所有图标会被重建, 并且之前的所有设置都会丢失. 没有特殊情况不要使用哦. 以免丢失之前的排列方式与文件夹. MAC OS X 10.10 应用程序下载失败后lunchpad产生灰色图标的解决办法,布布扣,bubuko.com

SQL Server 2008 R2中配置作业失败后邮件发送通知

SQL Server日常维护中难免会遇到作业失败的情况.失败后自然需要知道它失败了,除了例行检查可以发现出错以外,有一个较实时的监控还是很有必要的.比较专业的监控系统比如SCOM虽然可以监控作业执行情况在出错时进行报警,但对于DBA来说可能可定制性不高,最主要的是负责监控的人员在看到报警后一般都需要立刻联系DBA来解决,对于一些重要性不高的作业失败了,大半夜把你叫起来,感觉肯定是不爽的.SQL Server 本身支持发送数据库邮件,结合发送邮件的功能,在作业失败后将出错情况通过邮件通知DBA,这

Vpn error720 失败后的修复

某天,VPN突然链接失败,爆出 " 错误代码720不能建立到远程计算机的连接 您可能需要更改此连接的网络设置需要更多的协助". 出现错误720的原因主要是自动更新或者安装某软件后,TCP/IP协议出错,本地回环无法PING通,拨号出现错误720提示.有如下三种,大家可以尝试一下: 1.打开“控制面板”-“添加删除程序”,勾选“显示更新”,将此两个补丁卸载后重起计算机试试.KB893066和KB890923 2.把“C:\WINDOWS\system32\drivers”目录下的“TCP