1,当operator new无法满足内存需求时,抛出std::bad_alloc.
下面是一个验证的代码:
- #include <iostream>
- #include <stdexcept>
- using namespace std ;
-
- int main ()
- {
- try
- {
- int* p=NULL;
- while(1)
- p=new int[10000];
- }catch(std::bad_alloc&)
- {
- cout<<"no enough mem."<<endl;
- }
- return 0 ;
- }
#include <iostream>
#include <stdexcept>
using namespace std ;
int main ()
{
try
{
int* p=NULL;
while(1)
p=new int[10000];
}catch(std::bad_alloc&)
{
cout<<"no enough mem."<<endl;
}
return 0 ;
}
2,C++的一个公约:
当operator new无法满足需求时,它会在抛出exception前先调用一个专属的错误处理函数.
我们称之为:new-handler.
3,当operator无法满足内存需求时,它会不只一次的调用new-handler函数;
它会不断的重复调用,直到找到足够的内存.
一个设计良好的new-handler函数必须完成下面几件事:
(1)让更多内存可用.
例如:事先在程序起始处配置一大块内存,然后在new-handler第一次被调用时释放之.
(2)配置另外一个new-handler,其手上握有比较多的资源.
(3)卸除new-handler,set_new_handler(NULL)
将不再调用专属函数,而直接抛出exception.
(4)抛出exception.
(5)不回返,直接调用abort()或exit.
- #include <iostream>
- #include <stdexcept>
- using namespace std ;
-
- void noMoreMemory()
- {
- cout<<"Unable to satify request for memory."<<endl;
-
- abort();
-
-
- }
-
- int main ()
- {
-
-
-
- new_handler old_new_handler=set_new_handler(noMoreMemory);
-
- try
- {
- int* p=NULL;
- while(1)
- p=new int[10000];
- }catch(std::bad_alloc&)
- {
- cout<<"no more memory."<<endl;
- set_new_handler(old_new_handler);
- }
- set_new_handler(old_new_handler);
- return 0 ;
- }
#include <iostream>
#include <stdexcept>
using namespace std ;
void noMoreMemory()
{
cout<<"Unable to satify request for memory."<<endl;
//原则(5):不回返
abort();//不加,将会是一个死循环.
//原则(4):也可以通过抛出一个异常
//throw std::bad_alloc();
}
int main ()
{
//typedef void (*new_handler)(); 头文件中已经给出
//设定自己的专属错误处理函数.
//返回之前的new_handler
new_handler old_new_handler=set_new_handler(noMoreMemory);
//set_new_handler(NULL); //卸除new-handler,抛出异常.
try
{
int* p=NULL;
while(1)
p=new int[10000];
}catch(std::bad_alloc&)
{
cout<<"no more memory."<<endl;
set_new_handler(old_new_handler);
}
set_new_handler(old_new_handler);
return 0 ;
}
4,设定类class专属的new-handler.
一个强大的类模板.
- #include <iostream>
- #include <stdexcept>
- using namespace std ;
-
- template<class T>
- class NewHandlerSupport
- {
- public:
- static new_handler set_new_handler(new_handler p);
- static void* operator new(size_t size);
- static void* operator new[](size_t size);
- private:
- static new_handler currentHandler;
- };
-
- template<class T>
- new_handler NewHandlerSupport<T>::set_new_handler(new_handler p)
- {
- new_handler oldHandler=currentHandler;
- currentHandler=p;
- return oldHandler;
- }
-
- template<class T>
- void* NewHandlerSupport<T>::operator new(size_t size)
- {
-
- new_handler globalHandler=std::set_new_handler(currentHandler);
-
- void* memory;
- try
- {
-
- memory=::operator new(size);
- }catch(std::bad_alloc)
- {
- std::set_new_handler(globalHandler);
- throw;
- }
-
-
- std::set_new_handler(globalHandler);
- return memory;
- }
-
- template<class T>
- static void* NewHandlerSupport<T>::operator new[](size_t size)
- {
- return operator new(size);
- }
-
- template<class T>
- new_handler NewHandlerSupport<T>::currentHandler;
-
- void noMoreMemory()
- {
- cout<<"Unable to satify request for memory."<<endl;
-
- throw std::bad_alloc();
- }
-
- class X : public NewHandlerSupport<X>
- {
- };
-
- int main ()
- {
- X::set_new_handler(noMoreMemory);
- try
- {
- X* p=NULL;
-
- while(1)
- p=new X[100000];
- }catch(std::bad_alloc&)
- {
- cout<<"no more memory."<<endl;
- }
-
- X::set_new_handler(0);
- try
- {
- X* p=NULL;
-
- while(1)
- p=new X[100000];
- }catch(std::bad_alloc&)
- {
- cout<<"no more memory."<<endl;
- }
- return 0 ;
- }
#include <iostream>
#include <stdexcept>
using namespace std ;
template<class T>
class NewHandlerSupport
{
public:
static new_handler set_new_handler(new_handler p);
static void* operator new(size_t size);
static void* operator new[](size_t size);
private:
static new_handler currentHandler;
};
template<class T>
new_handler NewHandlerSupport<T>::set_new_handler(new_handler p)
{
new_handler oldHandler=currentHandler;
currentHandler=p;
return oldHandler; //返回之前的专属函数
}
template<class T>
void* NewHandlerSupport<T>::operator new(size_t size)
{
//下面调用标准的set_new_handler
new_handler globalHandler=std::set_new_handler(currentHandler);
void* memory;
try
{
//使用标准的new.
memory=::operator new(size);
}catch(std::bad_alloc)
{
std::set_new_handler(globalHandler);
throw; //继续抛出异常
}
std::set_new_handler(globalHandler); //返回原来的设置
return memory; //返回之前的专属函数
}
template<class T>
static void* NewHandlerSupport<T>::operator new[](size_t size)
{
return operator new(size);
}
template<class T>
new_handler NewHandlerSupport<T>::currentHandler; //设置为0
void noMoreMemory()
{
cout<<"Unable to satify request for memory."<<endl;
//abort();
throw std::bad_alloc();
}
class X : public NewHandlerSupport<X>
{
};
int main ()
{
X::set_new_handler(noMoreMemory);
try
{
X* p=NULL;
//先调用专属函数,然后有专属函数抛出异常.
while(1)
p=new X[100000];
}catch(std::bad_alloc&)
{
cout<<"no more memory."<<endl;
}
X::set_new_handler(0);
try
{
X* p=NULL;
//不再调用专属函数,直接捕获异常.
while(1)
p=new X[100000];
}catch(std::bad_alloc&)
{
cout<<"no more memory."<<endl;
}
return 0 ;
}
5,旧的编译器:
如果内存配置失败不会抛出异常,只是返回0.
测试实例:
int* p=new (nothrow)int;
if(p==0)
cout<<"memory error;"<<endl;
posted on 2010-05-13 14:37
何克勤 阅读(327)
评论(0) 编辑 收藏 所属分类:
C/C++