您的位置:首页 > 编程语言 > C语言/C++

C++专题分析------无法满足内存分配需求时的解决方法

2014-05-25 18:39 435 查看
operator new 和 operator delete仅适合用来分配单一对象;Arrays则由operator new[]和operator delete来操作。

对于一般函数的解决方法:调用一个客户指定的错误处理函数,即new-handler。为了指定这个用于处理内存不足的函数,客户必须调用set_new_handler,它是声明于<new>的标准库函数:

namespace std
{
typedef void (*new_handler)();
new_handler set_new_handler(new_handler p) throw();
}
new_handler是一个typedef(定义类型),定义一个指向函数的指针,该函数既没有参数也不返回任何东西;set_new_handler则是“获得一个new_handler并返回一个new_handler"的函数。throw()是一份异常明细。set_new_handler的参数是个指针,指向operator new 无法分配足够空间时该被调用的函数,返回值也是指针,指向那个被调用前正在执行的那个new-handler。

举例:

int main
{
std::set_new_handler(outOfMemo);
int *pBigDataArray = new int[10000];
.......
}

void outOfMemo
{
std::cerr<<"Unable to satisfy request for memory\n";
std::abort();
}
当operator new无法满足内存申请时,它会不断的调用new-handler函数,直到找到足够的内存。

对于专门的class解决方法:首先必须登录当operator new无法为一个Widget对象分配足够的存储空间时调用的函数,所以需要声明一个类行为new_handler的static成员。

class Widget
{
public:
static std::new_handler set_new_handler(std::new_handler p) throw();
static void* operator new(std::size_t size) throw(std::bad_alloc);
private:
static std::new_handler currentHandler;
};
/* Static成员必须在class之外被定义*/
std::new_handler Widget::currentHandler = 0;//在class实现文件内初始化为null。
/* Widget内的set_new_handler函数会将他获得的指针存储起来,然后返回先前存储的指针*/
std::new_handler Widget::set_new_handler(std::new_handler p) throw()
{
std::new_handler oldHandler = currentHandler;
currentHandler = P;
return oldHandler;
}

void* Widget::operator new(std::size_t size) throw(std::bad_alloc)
{
NewHandler h(std::set_new_handler(currentHandler));
return::operator new(size);
}


如果想要扩展对不同类的内存分配不足出现的问题,可以利用继承的方式:

template<typename T> <span style="font-family: Arial, Helvetica, sans-serif;">class NewHandlerSupport</span>
{
public:
static std::new_handler set_new_handler(std::new_handler p) throw();
static void* operator new(std::size_t size) throw(std::bad_alloc);
private:
static std::new_handler currentHandler;
};
template<typename T> <span style="font-family: Arial, Helvetica, sans-serif;">std::new_handler NewHandlerSupport<T>::set_new_handler(std::new_handler p) throw()</span>
{
std::new_handler oldHandler = currentHandler;
currentHandler = P;
return oldHandler;
}
<pre code_snippet_id="362667" snippet_file_name="blog_20140525_8_9277489" name="code" class="cpp">template<typename T> <span style="font-family: Arial, Helvetica, sans-serif;">void* NewHandlerSupport<T>::operator new(std::size_t size) throw(std::bad_alloc)</span>
{ NewHandler h(std::set_new_handler(currentHandler)); return::operator new(size);}

<span style="font-family: Arial, Helvetica, sans-serif;">template<typename T> std::new_handler Widget::currentHandler = 0;//在class实现文件内初始化为null。</span></span>
/*采用继承的方式*/
class Widget:public NewHandlerSupprt<Widget>
{......//和先前一样都不需要声明}



                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: