1,當(dāng)operator new無法滿足內(nèi)存需求時,拋出std::bad_alloc.
下面是一個驗(yàn)證的代碼:
- #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++的一個公約:
當(dāng)operator new無法滿足需求時,它會在拋出exception前先調(diào)用一個專屬的錯誤處理函數(shù).
我們稱之為:new-handler.
3,當(dāng)operator無法滿足內(nèi)存需求時,它會不只一次的調(diào)用new-handler函數(shù);
它會不斷的重復(fù)調(diào)用,直到找到足夠的內(nèi)存.
一個設(shè)計良好的new-handler函數(shù)必須完成下面幾件事:
(1)讓更多內(nèi)存可用.
例如:事先在程序起始處配置一大塊內(nèi)存,然后在new-handler第一次被調(diào)用時釋放之.
(2)配置另外一個new-handler,其手上握有比較多的資源.
(3)卸除new-handler,set_new_handler(NULL)
將不再調(diào)用專屬函數(shù),而直接拋出exception.
(4)拋出exception.
(5)不回返,直接調(diào)用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();//不加,將會是一個死循環(huán).
//原則(4):也可以通過拋出一個異常
//throw std::bad_alloc();
}
int main ()
{
//typedef void (*new_handler)(); 頭文件中已經(jīng)給出
//設(shè)定自己的專屬錯誤處理函數(shù).
//返回之前的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,設(shè)定類class專屬的new-handler.
一個強(qiáng)大的類模板.
- #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; //返回之前的專屬函數(shù)
}
template<class T>
void* NewHandlerSupport<T>::operator new(size_t size)
{
//下面調(diào)用標(biāo)準(zhǔn)的set_new_handler
new_handler globalHandler=std::set_new_handler(currentHandler);
void* memory;
try
{
//使用標(biāo)準(zhǔn)的new.
memory=::operator new(size);
}catch(std::bad_alloc)
{
std::set_new_handler(globalHandler);
throw; //繼續(xù)拋出異常
}
std::set_new_handler(globalHandler); //返回原來的設(shè)置
return memory; //返回之前的專屬函數(shù)
}
template<class T>
static void* NewHandlerSupport<T>::operator new[](size_t size)
{
return operator new(size);
}
template<class T>
new_handler NewHandlerSupport<T>::currentHandler; //設(shè)置為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;
//先調(diào)用專屬函數(shù),然后有專屬函數(shù)拋出異常.
while(1)
p=new X[100000];
}catch(std::bad_alloc&)
{
cout<<"no more memory."<<endl;
}
X::set_new_handler(0);
try
{
X* p=NULL;
//不再調(diào)用專屬函數(shù),直接捕獲異常.
while(1)
p=new X[100000];
}catch(std::bad_alloc&)
{
cout<<"no more memory."<<endl;
}
return 0 ;
}
5,舊的編譯器:
如果內(nèi)存配置失敗不會拋出異常,只是返回0.
測試實(shí)例:
int* p=new (nothrow)int;
if(p==0)
cout<<"memory error;"<<endl;
posted on 2010-05-13 14:37
何克勤 閱讀(335)
評論(0) 編輯 收藏 所屬分類:
C/C++