[C++]定制new和delete

定制new和delete

本文讨论C++内存管理的例程行为,此行为的主角是分配例程和归还例程,配角是new-handler,这是当operator new无法满足客户的内存需求时所调用的函数。

了解new-handler的行为

当operator new抛出异常以反映一个未获满足的内存需求之前,它首先会调用一个客户指定的错误处理函数,所谓的new-handler。客户可以指定set_new_handler,在内:

namespace std {
typedef void (*new_handler)();
new_handler set_new_handler(new_handler) _NOEXCEPT;
}

实例程序:

void out_of_num() {
    cerr << "out of range" << endl;
    abort();
}
int main() {
    std::set_new_handler(out_of_num);
    int* bidArray = new int[100000000L];
    //  ...
    return 0;
}

在我的IDE中并不会出现问题,因为足够分配这么大的空间。但如果operator new无法分配这么大的空间,out_of_num就会被调用。当operator new无法满足内存申请时,他会不断调用new-handler函数,知道找到足够内存。

那么一个设计良好的new-handler应该做什么呢:

  • 让更多内存可被使用。程序一开始执行就分配一大块内存,然后当new-handler第一次调用时,将他们释还给程序使用。
  • 安装另一个new-handler。如果目前new-handler无法取得更多可用内存,就调用其他的new-handler来替换自己。
  • 卸除new-handler也就是将null指针传给 ‘set_ new_ handler’。一旦没有安装任何new-handler,operator new会在内存分配不足时抛出异常。
  • 抛出bad_alloc
  • 不返回调用abort/exit。

我们希望能够以不同的方式处理内存分配失败的情况,而且视被分配无属于哪个class而定:

这里写图片描述

C++并不支持class专属之new-handler,但其实并需要,我们可以自己实现这种行为。

photo2:

static成员必须在class定义式之外被定义:

std::new_handler Widget::currentHandler = 0;

Widget内的set_new_handler会将原来的指针存储起来,然后返回先前存储的指针:

这里写图片描述

最后new要做以下事情:

  • 调用set_new_handler,告诉Widget的错误处理函数。
  • 调用global operator new,执行实际之内存分配。
  • 如果global operator new能够分配足够一个Widge对象所用的内存,Widget的operator new会返回一个指针,指向分配所得。

这里写图片描述

这里写图片描述

这里写图片描述

实现这一方案的代码并不因class的不同而不同,因此在它处加以复用是个合理的构想。

这里写图片描述

有了这个class template,只要让Widget继承相应的template就可以了。

class Widget : public NewHandlerSupport<Widget> {
    ....
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值