sailing

Everything...

安装处理new operator无法获取足够内存时候的处理函数

在通常的情况下,调用new操作的时候,一般都不会去关心是否有足够的内存使得这个操作可以成功。但是做为一个完美的程序,有必要去处理一下内存不够的情况。
在默认情况下,内存分配失败会导致返回null或者抛出一个std::bad_alloc异常,所以需要在每次new的时候检查返回值是否为NULL或者在new上包裹一个try catch块。不过,除了每次不厌其烦得关心new是否成功,我们可以利用C++提供的set_new_handler函数来注册一个内存分配失败后的回调函数。set_new_handler函数接受一个如下定义的函数指针:
typedef void ( *new_handler )( );

当可用内存不足导致new操作失败的时候,如果有注册一个new_handler, new操作内部就会反复调用你注册的handler,然后重新尝试分配内存(所以你可以利用new_handler来释放一些不需要的内存,保证程序顺利运行)。当然,如果你没有注册new_handler,它就要抛出一个异常了。具体可以参考下面这段代码:

       while ((p = malloc(size)) == 0)

                if (_callnewh(size) == 0)

                {       // report no memory

                static const std::bad_alloc nomem;

                _RAISE(nomem);

                }

 

        return (p);

总结一下new_handler的用处
1 释放内存,保证new操作顺利执行
2 方便对new操作的异常处理,只需要注册一次,不需要每次在new操作之后检查或者捕捉异常

下面是new操作的用法举例:
1. 内存不足时,写log,然后释放不需要的内存
#include "stdafx.h"

#include <iostream>

#include <limits.h>

using namespace std;

 

void myHandler()

 

{

    cerr<<"error doing new"<<endl;
    //可以在这里释放一些内存

}

 

int _tmain(int argc, _TCHAR* argv[])

{

    set_new_handler(myHandler);

    int MemoryNeed = INT_MAX;

    void *p = ::operator new(MemoryNeed);

    return 0;

 

}

2. 也可以在首次调用new_handler之后更改/移除处理函数,实现灵活的内存分配逻辑:

#include "stdafx.h"

#include <iostream>

#include <limits.h>

using namespace std;

 

void myHandler2()

{

    cerr<<"new way to handler insufficient memory"<<endl;

    //在第二次执行后移除处理函数,利用默认机制抛出异常

    set_new_handler(NULL);

}

 

void myHandler()

{

    cerr<<"error doing new"<<endl;

    //在第一次执行后设置新的处理函数

    set_new_handler(myHandler2);

}

 

int _tmain(int argc, _TCHAR* argv[])

{

    set_new_handler(myHandler);

    int MemoryNeed = INT_MAX;

    void *p = ::operator new(MemoryNeed);

    return 0;

}

输出结果如下:

posted on 2007-03-17 18:37  乌生鱼汤  阅读(333)  评论(0编辑  收藏  举报

导航