new ps内存不足怎么办 求助

提高C++代码质量&-&[030]new内存失败后的正确处理
char* pStr = new string[SIZE];
if (NULL = pStr)
&&& //error
processing
&&& return
以上代码存在的问题是:
如果new分配内存成功,NULL ==
pStr不会成立;而如果分配失败,new就会抛出bad_alloc异常并跳过后面的代码,不会执行到if (NULL ==
更加明确一些,先来看看相关声明
namespace std
//new and delete
void* operator new(std::size_t)
throw(std::bad_alloc);
void operator delete(void*)
//array new and delete
void* operator new[](std::size_t)
throw(std::bad_alloc);
void operator delete[](void*)
//placement new and delete
void* operator new(std::size_t, void*)
void operator delete(void*, void*)
//placement array new and delete
void* operator new[](std::size_t,
void*) throw();
void operator delete[](void*, void*)
通过以上声明,按照C++标准,如果想检查new是否成功,则应该捕捉异常:
&&& char* pStr =
new string[SIZE];
...//processing codes
catch (const bad_alloc&
&&& return
但是为了使在标准制定之前已经存在的代码能够继续正常运行,C++标准化委员会并不想遗弃Test-for-NULL的代码,所以他们提供了operator
new的另一种可选形式—nothrow,用以提供传统的Failure-yields-NULL行为。其实现原理如下:
void* operator new(size_t cb, const
std::nothrow_t&) throw()
&&& char*p;
p = new char[cb];
(std::bad_alloc& e)
&&& return
&new&文件中也声明了nothrow new的重载版本:
namespace std
&&& struct
&&& extern const
//new and delete
void* operator new(std::size_t,
std::nothrow_t const&) throw();
void operator delete(void*,
std::nothrow_t const&) throw();
//array new and delete
void* operator new[](std::size_t,
std::nothrow_t const&) throw();
void operator delete[](void*,
std::nothrow_t const&) throw();
如果采用不抛出异常的new形式,本建议开头的代码片段就应该改写为以下形式:
char* pStr = new(std::nothrow)
string[SIZE];
if (NULL == pStr)
&&& ...//error
processing
使用nothrow new只能保证operator
new不会抛出异常,无法保证“new(std::nothrow)
ClassN”这样的表达式不会抛出异常,因为在ClassName的构造函数中,有可能也new了一些内存。所以,慎用nothrow
另外一点需要说明的是,在Visual C++ 6.0中operator
new、operator new(std::nothrow)和STL之间不兼容,且不能完全被修复。如果在非MFC项目中使用Visual
6.0中的STL,其即装即用的行为可能导致STL在内存不足的情况下让程序崩溃。对于基于MFC的项目,STL是否能够幸免于难,完全取决于你使用的STL针对operator
new的异常处理。这一点在James
Hebben的文章《不要让内存分配失败导致您的旧版STL应用程序崩溃》中进行了详细的介绍。
当使用new申请一块内存失败时,抛出异常std::bad_alloc是C++标准中规定的标准行为,所以推荐使用try{p = new
int[SIZE];}catch (const std::bad_alloc&
e){...}的处理方式。但是在一些老旧的编译器中,却不支持该标准,它会返回NULL,此时具有C传统的Test_for_NULL代码便起了作用。
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!&&|&&
LOFTER精选
网易考拉推荐
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
历史上的今天
loftPermalink:'',
id:'fks_084067',
blogTitle:' 内存不足的原因
blogAbstract:'&\r\n\r\n&\r\n\r\n一、剪贴板占用了太多的内存 \r\n  实际上,剪贴板是内存中的一块临时区域,当你在程序中使用了“复制”或“剪切”命令后,Windows将把复制或剪切的内容及其格式等信息暂时存储在剪贴板上,以供“粘贴”使用。如果当前剪贴板中存放的是一幅图画,则剪贴板就占用了不少的内存。这时,请按下述步骤清除剪贴板中的内容,释放其占用的内存资源: \r\n  1.单击“开始”,指向“程序”或“所有程序”,指向“附件”,指向“系统工具”,然后单击“剪贴板查看程序”,打开“剪贴板查看程序”窗口。2.在“编辑”菜单上,单击“删除”命令。3.关闭“剪贴板查看程序”窗口。 ',
blogTag:'',
blogUrl:'blog/static/',
isPublished:1,
istop:false,
modifyTime:0,
publishTime:8,
permalink:'blog/static/',
commentCount:0,
mainCommentCount:0,
recommendCount:0,
bsrk:-100,
publisherId:0,
recomBlogHome:false,
currentRecomBlog:false,
attachmentsFileIds:[],
groupInfo:{},
friendstatus:'none',
followstatus:'unFollow',
pubSucc:'',
visitorProvince:'',
visitorCity:'',
visitorNewUser:false,
postAddInfo:{},
mset:'000',
remindgoodnightblog:false,
isBlackVisitor:false,
isShowYodaoAd:false,
hostIntro:'',
hmcon:'0',
selfRecomBlogCount:'0',
lofter_single:''
{list a as x}
{if x.moveFrom=='wap'}
{elseif x.moveFrom=='iphone'}
{elseif x.moveFrom=='android'}
{elseif x.moveFrom=='mobile'}
${a.selfIntro|escape}{if great260}${suplement}{/if}
{list a as x}
推荐过这篇日志的人:
{list a as x}
{if !!b&&b.length>0}
他们还推荐了:
{list b as y}
转载记录:
{list d as x}
{list a as x}
{list a as x}
{list a as x}
{list a as x}
{if x_index>4}{break}{/if}
${fn2(x.publishTime,'yyyy-MM-dd HH:mm:ss')}
{list a as x}
{if !!(blogDetail.preBlogPermalink)}
{if !!(blogDetail.nextBlogPermalink)}
{list a as x}
{if defined('newslist')&&newslist.length>0}
{list newslist as x}
{if x_index>7}{break}{/if}
{list a as x}
{var first_option =}
{list x.voteDetailList as voteToOption}
{if voteToOption==1}
{if first_option==false},{/if}&&“${b[voteToOption_index]}”&&
{if (x.role!="-1") },“我是${c[x.role]}”&&{/if}
&&&&&&&&${fn1(x.voteTime)}
{if x.userName==''}{/if}
网易公司版权所有&&
{list x.l as y}
{if defined('wl')}
{list wl as x}{/list}转自:/html/70/n-827070.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[000L];...}  当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)();&&&&&&&&&& else&&&&&&&&&&&&&&&&&& throw std::bad_alloc();&&&&&& }}转自:.cn/s/blog_9f1cs.html&使用new分配内存失败时往往会使用asert()终止程序,但是这只能在除错模式下abert函数才能有效,在生产模式下,abert只是一个void指令,所以连程序都跳不出来。&&&&而当new操作失败时,一个好的程序不能简单的终止程序就行了,而是要尝试去释放内存&&&&如何能在new操作失败,在抛出异常之前先把相应的处理做了呢?这就要用到new_handler了,它是在抛出exception调用的。为了指定这个所谓的“内存不足处理函数,new_handler”,client必须调用set_new_handler,这是头文件提供的函数,用法:&&&&typedef void (*new_handler)()&&&&new_handler set_new_handler(new_handler p) throw();简单的程序测试:#include &stdafx.h&#include#includvoid NoMoreMemory(){cout&&&Unable to statisty request for memory&&&abort();}int _tmain(int argc, _TCHAR* argv[]){set_new_handler(NoMoreMemory);int *p=new int[];return 0;}注:当operator new 无法满足内存需求时,它会不只一次地调用new_handler函数(如果new_handler没有退出程序的话);它会不断地调用,直到找到足够的内存为止。因此一个良好设计的new_handler函数必须完成下列事情之一:1)让更多的内存可用。这或许能够让operator new 的下一次内存配置行为成功。实现此策略的方法之一就是在程序起始时配置一大块内存,然后在new_handler第一次被调用时释放之。如此的释放动作常常伴随着某种警告信息,告诉用户目前的内存已经处于低水位,再来的内存需求可能失败,除非有更多的内存回复自由身。2)安装一个不同的new_handler,如果目前的new_handler无法让更多的内存可用,或许它知道另一个new_handler手上我有比较多的资源。果真如此,目前的new_handler就可以安装另外一个new_handler以取代自己(只要再调用一次set_new_handler即可)。当operator new下次调用new_handler函数时,它会调用最新安装的那个。3)卸除掉这个new_handler,也就是说,将null指针传给set_new_handler,一旦没有安装任何new_handler,operator new就会在内存配置失败时抛出一个类型为std::bad_alloc的exception。4)抛出一个exception,类型为std::bad_alloc(或者派生类型)。这样的exception不会被operator new捕获,所以它们就会传动到最初踢出内存需求的那个点上5)不返回,直接调用abort或exit
最新教程周点击榜
微信扫一扫我的电脑不能处理新的程序,因为内存不足了。的海词问答与网友补充:
相关词典网站:

我要回帖

更多关于 new bitmap 内存不足 的文章

 

随机推荐