概述
在系统还有充足内存的情况下(内存占用率不到45%), new操作失败(返回空指针),用malloc也是如此! 请问是什么原因?x5v A`UM9W6KK:Fh q
注:new操作申请的内存大小是远小于系统内存大小的。实际上只是new了1M的空间,而且之前new同样大小的内存是成功的,系统运行了一会儿,就会在这里失败。 一查,是new操作返回0, 而系统还有足够的内存。T'h"Co)W#]#D
请问高手这可能是什么原因呢? 谢谢!!!!
代码太多了,没法贴上来啊。但是出问题的地方就是在这里:
//下面的代码在loadFile 函数里面
if(m_pBits)
{
delete [] m_pBits;//m_pBits 是一个BYTE* 类型成员,构造函数里面初始化为NULL
m_pBits = NULL;
}
//new 之前得到系统内存状态,还有充足的内存!
MEMORYSTATUS MemStat;
MemStat.dwLength = sizeof(MEMORYSTATUS);
GlobalMemoryStatus(&MemStat); //执行之后查看到系统内存, 在new失败的情况下,占用率也只是42%左右
{A#f8U1Y*nm_pBits = new BYTE[10000....大约1M]; //这里以前执行过多次,都没有问题Q#U&d,gu?1w:l
'l.dX _| |!TBwn{o2Nhm_pBits = fread(....) //出错,调试发现fread之前m_pBits居然是0!!!
==========================================
new一个比较小的内存看是否成功,若不成功重建工程,如果成功的话可能没有连续内存空间
==========================================
可以用下面的方法看看是什么原因.
try{
.. = new ..
}catch(exception &e){
cout < <e.What() < <endl;
}
==========================================
上次我的工程也那样
所有的new都不成功
最后是我是重建工程拷贝文件过去
遇到过同样的问题~!
至今不知原因
重建工程可以解决!~
==========================================
C++ new的nothrow关键字和new_handler用法
今天和同事review代码时,发现这样的一段代码:
Manager * pManager = new Manager();
if(NULL == pManager)
{
//记录日志
return false;
}
然后,一个同事就说这样写欠妥,应该改为:
Manager * pManager = NULL;
try
{
pManager = new Manager();
}
catch(std::bad_alloc e)
{
//...
}
我查了一下资料,发现:
1.malloc分配时,如果内存耗尽分配不出来,会直接返回NULL;
2.早期C++版本,new分配时,如果内存耗尽分配不出来,也会直接返回NULL;
3.现代编译器,如gcc和VC,则都在分配不出内存时,抛出异常;
4.但是,在面对不支持异常的嵌入式环境,或者编程人员不喜欢使用异常结构时,则也有办法解决,即关键字nothrow,如以下代码:
#include <new>//必须使用new头文件
Manager * pManager = new (std::nothrow) Manager();
if(NULL == pManager)
{
//记录日志
return false;
}
================================================
5.如果您不想使用关键字nothrow,该如何解决这个问题呢?也可以解决,即替换new_handler即可。
想知道为何替换new_handler就能解决这个问题,需要理解new分配时,内存耗尽是如何抛出异常的。每当new分配内存,而没有足够的内存可供分配时,它会调用new_handler函数,而缺省的new_handler函数,会抛出throw bad_alloc()。为了避免抛出这个异常,可以替换一个不抛出异常的new_handler即可。
typedef void (*new_handler)();
new_handler set_new_handler(new_handler p) throw();
new_handler是一个自定义的函数指针类型,它指向一个没有输入参数也没有返回值的函数。
set_new_handler是一个输入并返回new_handler类型的函数。
set_new_handler的输入参数是operator new分配内存失败时要调用的出错处理函数的指针,返回值是set_new_handler没调用之前就已经在起作用的旧的出错处理函数的指针。
如以下代码:
#include <new>
#include <iostream>
#include <stdlib.h>
using namespace std;
void __cdecl newhandler()
{
return;
}
int main()
{
set_new_handler (newhandler);
Manager * pManager = new (std::nothrow) Manager();
if(NULL == pManager)
{
//记录日志
return false;
}
}
==========================================================================================================
new 失败的问题
c++ 标准 new 失败是抛出异常的,new(std::nothrow) 才返回 NULL
为什么公司里面就都用 NULL 判断呢? 好像公司里面好多人都不知道异常怎么用的?
有多少公司的代码是异常安全的?
求解?
看着他们的代码实在是头大
------解决方案--------------------------------------------------------
因为好多公司都禁用异常.
------解决方案--------------------------------------------------------
------解决方案--------------------------------------------------------
代码比较古老了 曾经的new是失败返回NULL的 而之所以现在又nothrow也是为了向下兼容
------解决方案--------------------------------------------------------
异常处理显得代码有些冗长,用NULL判断更方便些,在编码上少敲几个字母就是胜利了,不过条件不出错
------解决方案--------------------------------------------------------
C++的代码本来就不容易写,要追求异常安全就更难了。不过,对于申请内存来说,绝大多数程序,不太会失败。就算失败了,由于内存耗尽而crash的应用程序也可以接受。对于64位的应用来说,更是如此。因此,应用程序虽然异常不安全,但大多数情况下也能凑和着用。
------解决方案--------------------------------------------------------
没有思考过这个问题,翻了资料,
楼主说的是对的,抛出bad_alloc异常来,注:并没有说会返回null
只有 另外一个版本:
void* operator new(大小,nothrow); 这个分配失败才会返回NULL.
用法: int* p= new(nothrow) int;
if(p==NULL)
{
}
else
{
}
------解决方案--------------------------------------------------------
malloc倒是会 返回NULL.
教材害死人啊, 我记得我以前的教材也是这样检测的。
顺便问个问题, operator new(大小) operator new(大小,const std::nothrow&) thrown();
这两个版本 官方说,不需要包含什么头文件,什么原因???
平时我们用任何函数,都是需要包含头文件的, new 运算符的本质是调用 operator new函数。。。。
为什么不包含头文件呢???
------解决方案--------------------------------------------------------
这不都关键字了吗...
------解决方案--------------------------------------------------------
我们在大学学C++的时候都不讲异常处理的。。。都自己看得
------解决方案--------------------------------------------------------
我们的目的是为了让程序健壮,而不是出了点问题就让程序直接退出。
先弄清异常与错误的分别吧。
------解决方案--------------------------------------------------------
检查一下连接库用的是哪个版本的new
------解决方案--------------------------------------------------------
异常是很方便的功能,但并不是必须的功能
第一,较小的程序,架构较简单的程序,不必非要用异常
第二,异常机制是要消耗资源的,有些时候能省则省,例如《more effective c++》
------解决方案--------------------------------------------------------
new出错是要出异常的,因此后边的判断if (NULL == p)根本执行不到,只不过异常一般用的比较少而已
------解决方案--------------------------------------------------------
使用new ,然后判断返回是否为NULL的意义不大,除非你用的实际上是malloc
可以考虑用try() catch()
------解决方案--------------------------------------------------------
因为bad_alloc并不总是存在,C++允许编译器使用空异常规范的分配函数,这时候就只有NULL了。
------解决方案--------------------------------------------------------
这个问题我以前也疑惑过,按标准来说
int * p = new p;
if( p == NULL )
{
// 按照标准如果不指定nothrow,这里是不执行的
}
但事实是,我们的代码能正常执行,其实这个很多人都不知道,我在网上也问了很久,后来有人说,
这是编译器做的更改.微软的编译器,不管你指没指定nothrow,代码都是执行的,所以没有人去关注nothrow了。现在默认都是这样写的了。
------解决方案--------------------------------------------------------
主要是普通开发人员处理不好内存,而new这个东西,必然要编译器处理,系统就越做越多,干脆隐藏了动作。
------解决方案--------------------------------------------------------
不懂什么问题
------解决方案--------------------------------------------------------
楼上说 #define new new(std::nothrow)
mfc中的 new也是被重新定义了,貌似叫:DEBUG_NEW 吧,也是一个宏
你定义后,会和mfc冲突了,造成它的无效啊
最后
以上就是无聊洋葱为你收集整理的C++为什么new(malloc)操作会失败的全部内容,希望文章能够帮你解决C++为什么new(malloc)操作会失败所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复