概述
在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 memoryn";
std::abort();
}
使用noMemoryToAlloc函数的代码为:
int main()
{
set_new_handler(noMemoryToAlloc);
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)();
else
throw std::bad_alloc();
}
}
最后
以上就是曾经乌龟为你收集整理的采用new分配内存失败时为什么会出现两种错误报告方式?的全部内容,希望文章能够帮你解决采用new分配内存失败时为什么会出现两种错误报告方式?所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复