new和malloc的区别
Posted reflecter
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了new和malloc的区别相关的知识,希望对你有一定的参考价值。
共有10个区别,如表格中所示:
1、申请的内存所在位置不同----new在自由存储区,malloc在堆
new操作符是 从自由储存区(free store)上 为对象 动态分配 内存空间 ,而malloc函数 从堆上 动态分配 内存空间。
附:
自由存储区是C++基于new操作符的一个抽象概念。其定义 是 凡是通过new操作符进行内存申请,该内存即为自由存储区。
堆 是操作系统的 术语 ,是操作系统所维护的一块特殊内存,用于程序的内存动态分配。在C语言中,使用malloc从堆上分配内存,然后使用free释放已经分配的内存。
那么,自由存储区 能否与 堆 等价?
自由存储区不仅可以是堆,还可以是静态存储区。
特殊地,经过重载的new运算符可以不为对象分配内存。
new (place_address) type
place_address为一个指针,代表一块内存地地址。当使用上面这种仅以一个地址调用new操作符时,new操作符不分配任何内存,只是简单地返回指针实参,然后在place_address指定地地址进行对象地初始化工作。
2、返回类型的安全性不同 -----new返回完整类型指针,malloc返回void*
new操作符内存分配成功时,返回的是对象类型的指针,类型严格与对象严格匹配,无需进行类型转换,故new是符合类型安全性的操作符。
malloc内存分配成功时则是返回void*,需要进行强制类型转换成我们需要的类型。
另:类型安全很大程度上等价于内存安全,类型安全的代码不会试图分配自己没被授权的内存区域。
3、内存分配失败时的返回值----new会抛出异常,malloc返回NULL
new内存分配失败时,会抛出bac_alloc异常,它不会返回NULL;
malloc分配内存失败时,则返回NULL。因此,在C语言中习惯在分配内存之后判断是否分配成功。
int *a = (int *) malloc( sizeof(int)); if( NULL == a) { ... } ...
4、是否需要指定内存块大小----new自动计算,malloc需要显示指出
new操作符申请内存分配时无须指定内存块的大小,编译器会根据类型信息自动计算
malloc需要显示地指出内存地尺寸,如上的 sizeof(int)
5、是否调用构造函数/析构函数----new调用,而malloc不会
new操作符来分配对象会经历3个步骤:
(1) 调用operator new函数(对于数组是operator new[])分配一块足够大的、原始的、未命名的内存空间以便存储特定类型的对象
(2) 编译器运行相应的构造函数以构造对象,并为其传入初值
(3) 对象构造完成后,返回一个指向该对象的指针
delete操作符释放对象内存经历2个步骤:
(1) 调用对象的析构函数
(2) 编译器调用operator delete (或 operator delete[])函数来释放内存空间。
6、对数组的处理-
C++提供了 new[]和delete[]专门来处理数组类型。
而至于malloc,它并不知道你在这块内存上要放数组还是啥东西,反正它就给你一块原始的内存,再给你一个内存的地址就完事了。所以在动态分配一个数组的内存,还需要手动指定数组的大小。
7、new与malloc是否可以相互调用
operator new 或 operator delete 的实现可以基于malloc,而malloc的实现不可以去调用new。
下面是编写operator new和operator delete的一种简单方式:
void* operator new(sieze_t size) { void* mem=malloc(size); if(NULL != mem) reutrn mem; else throw bad_alloc(); } void* operator delete(void* mem)noexcept { free(mem); }
8、是否可以被重载
operator new / operator delete可以被重载。
new 和 delete共有8个重载版本:
//这些版本可能抛出异常 void * operator new(size_t); void * operator new[](size_t); void * operator delete (void * )noexcept; void * operator delete[](void *0)noexcept; //这些版本承诺不抛出异常 void * operator new(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;
malloc / free 不允许重载
9、能否直观地重新分配内存
malloc分配内存之后,如果在使用过程中发现内存不足,可以使用realloc函数进行内存重新分配,以实现内存的扩充。
realloc函数先判断当前指针所指的内存是否有足够的连续空间。如果有,原地扩大可分配的内存地址。如果没有,先按照新指定的大小分配空间,将原有数据从头到尾拷贝到新分配的内存区域,最后释放原来的内存区域。
new 没有这样直观的配套函数来扩充内存。
10、客户处理内存分配不足
以上是关于new和malloc的区别的主要内容,如果未能解决你的问题,请参考以下文章