早期malloc分配时,如果内存耗尽分配不出来,会直接返回NULL。现在分配不出来,直接抛出异常(可使用nothrow关键字)

Posted 朝闻道

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了早期malloc分配时,如果内存耗尽分配不出来,会直接返回NULL。现在分配不出来,直接抛出异常(可使用nothrow关键字)相关的知识,希望对你有一定的参考价值。

今天和同事review代码时,发现这样的一段代码:

 

Manager * pManager = new Manager();

if(NULL == pManager)

{

    //记录日志

    return false;

}

 

然后,一个同事就说这样写欠妥,应该改为:

 

Manager * pManager = NULL;

try

{

    pManager = new Manager();

}

catch(std::bad_alloc e)

{

    //...

}

 

我查了一下资料,发现:

1.malloc分配时,如果内存耗尽分配不出来,会直接返回NULL;

2.早期C++版本,new分配时,如果内存耗尽分配不出来,也会直接返回NULL;

3.现代编译器,如gcc和VC,则都在分配不出内存时,抛出异常;

4.但是,在面对不支持异常的嵌入式环境,或者编程人员不喜欢使用异常结构时,则也有办法解决,即关键字nothrow,如以下代码:

 

#include <new>//必须使用new头文件

 

Manager * pManager = new (std::nothrow) Manager();

if(NULL == pManager)

{

    //记录日志

    return false;

}

 

================================================

 

5.如果您不想使用关键字nothrow,该如何解决这个问题呢?也可以解决,即替换new_handler即可。

 

想知道为何替换new_handler就能解决这个问题,需要理解new分配时,内存耗尽是如何抛出异常的。每当new分配内存,而没有足够的内存可供分配时,它会调用new_handler函数,而缺省的new_handler函数,会抛出throw bad_alloc()。为了避免抛出这个异常,可以替换一个不抛出异常的new_handler即可。

 

typedef void (*new_handler)();
new_handler set_new_handler(new_handler p) throw();

new_handler是一个自定义的函数指针类型,它指向一个没有输入参数也没有返回值的函数。
set_new_handler是一个输入并返回new_handler类型的函数。
set_new_handler的输入参数是operator new分配内存失败时要调用的出错处理函数的指针,返回值是set_new_handler没调用之前就已经在起作用的旧的出错处理函数的指针。

 

如以下代码:

 

#include <new>
#include <iostream>
#include <stdlib.h>

using namespace std;

void __cdecl newhandler()
{
    return;
}

int main()
{
    set_new_handler (newhandler);

    Manager * pManager = new (std::nothrow) Manager();
    if(NULL == pManager)
    {
        //记录日志
        return false;
    }
}

http://blog.csdn.net/huyiyang2010/article/details/5984987

以上是关于早期malloc分配时,如果内存耗尽分配不出来,会直接返回NULL。现在分配不出来,直接抛出异常(可使用nothrow关键字)的主要内容,如果未能解决你的问题,请参考以下文章

malloc分配内存的结构

malloc函数的原理是啥啊?

memcached 的内存分配器是如何工作的?为什么不适用 malloc/free!?为何要使用 slabs?

memcached 的内存分配器是如何工作的?为什么不适用 malloc/free!?为何要使用 slabs?

怎么查看动态分配内存空间的大小(c语言)。

为啥反复分配和释放内存会耗尽系统所有内存?