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

本文详细介绍了C++中使用operatornew和operatordelete进行内存管理的方法,包括如何处理内存不足的情况以及如何为特定类自定义内存分配错误处理函数。通过实例演示了如何在类内部设置和使用new-handler来捕获和处理内存分配失败的异常。

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>
{......//和先前一样都不需要声明}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FeelTouch Labs

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值