HTML5技术

细说new与malloc的10点区别 - melonstreet(2)

字号+ 作者:H5之家 来源:H5之家 2016-01-20 14:00 我要评论( )

void * operator new (sieze_t size){ if ( void * mem = malloc(size) return mem; else throw bad_alloc();}( void *mem) noexcept {free(mem);} 8.是否可以被重载 opeartor new /operator delete可以被重载。标

void * operator new (sieze_t size) { if(void * mem = malloc(size) return mem; else throw bad_alloc(); } (void *mem) noexcept { free(mem); }

8.是否可以被重载

opeartor new /operator delete可以被重载。标准库是定义了operator new函数和operator delete函数的8个重载版本:

(size_t); void * operator new[](size_t); void * operator delete (void * )noexcept; void * operator delete[](void *0)noexcept; (size_t ,nothrow_t&) noexcept; void * operator new[](size_t, nothrow_t& ); void * operator delete (void *,nothrow_t& )noexcept; void * operator delete[](void *0,nothrow_t& )noexcept;

我们可以自定义上面函数版本中的任意一个,前提是自定义版本必须位于全局作用域或者类作用域中。太细节的东西不在这里讲述,总之,我们知道我们有足够的自由去重载operator new /operator delete ,以决定我们的new与delete如何为对象分配内存,如何回收对象。

而malloc/free并不允许重载。

9. 能够直观地重新分配内存

使用malloc分配的内存后,如果在使用过程中发现内存不足,可以使用realloc函数进行内存重新分配实现内存的扩充。realloc先判断当前的指针所指内存是否有足够的连续空间,如果有,原地扩大可分配的内存地址,并且返回原来的地址指针;如果空间不够,先按照新指定的大小分配空间,将原有数据从头到尾拷贝到新分配的内存区域,而后释放原来的内存区域。

new没有这样直观的配套设施来扩充内存。

10. 客户处理内存分配不足

在operator new抛出异常以反映一个未获得满足的需求之前,它会先调用一个用户指定的错误处理函数,这就是new-handler。new_handler是一个指针类型:

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

指向了一个没有参数没有返回值的函数,即为错误处理函数。为了指定错误处理函数,客户需要调用set_new_handler,这是一个声明于的一个标准库函数:

namespace std { new_handler set_new_handler(new_handler p ) throw(); }

set_new_handler的参数为new_handler指针,指向了operator new 无法分配足够内存时该调用的函数。其返回值也是个指针,指向set_new_handler被调用前正在执行(但马上就要发生替换)的那个new_handler函数。

对于malloc,客户并不能够去编程决定内存不足以分配时要干什么事,只能看着malloc返回NULL。

总结

将上面所述的10点差别整理成表格:

特征 new/delete malloc/free

分配内存的位置 自由存储区 堆

内存分配失败返回值 完整类型指针 void*

内存分配失败返回值 默认抛出异常 返回NULL

分配内存的大小 由编译器根据类型计算得出 必须显式指定字节数

处理数组 有处理数组的new版本new[] 需要用户计算数组的大小后进行内存分配

已分配内存的扩充 无法直观地处理 使用realloc简单完成

是否相互调用 可以,看具体的operator new/delete实现 不可调用new

分配内存时内存不足 客户能够指定处理函数或重新制定分配器 无法通过用户代码进行处理

函数重载 允许 不允许

构造函数与析构函数 调用 不调用

malloc给你的就好像一块原始的土地,你要种什么需要自己在土地上来播种

而new帮你划好了田地的分块(数组),帮你播了种(构造函数),还提供其他的设施给你使用:

当然,malloc并不是说比不上new,它们各自有适用的地方。在C++这种偏重OOP的语言,使用new/delete自然是更合适的。

感谢您的耐心阅读。
文章链接:

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • 【.net 深呼吸】细说CodeDom(2):表达式、语句 - 东邪独孤

    【.net 深呼吸】细说CodeDom(2):表达式、语句 - 东邪独孤

    2016-12-13 12:00

  • 细说ASP.NET Core与OWIN的关系 - 偏僻的维度

    细说ASP.NET Core与OWIN的关系 - 偏僻的维度

    2016-06-04 13:00

  • 匹夫细说C#:妥协与取舍,解构C#中的小数运算 - 慕容小匹夫

    匹夫细说C#:妥协与取舍,解构C#中的小数运算 - 慕容小匹夫

    2015-10-25 13:06

网友点评
o