new、delete、malloc、free、realloc的区别

1、属性

new/delete是C++的运算符,malloc/free是标准库函数

2、参数

new运算符根据数据类型,自动决定其大小,不使用sizeof运算符,而malloc要指定分配存储空间的大小。

3、返回类型

new返回指向此类型的指针,不用进行强制类型转换。故new是符合类型安全性的操作符。malloc返回指向void *类型的指针,需要进行强制类型转换。

4、初始化

new是一个分配内存并进行初始化的过程,例如,cha *p = new char(‘a');而malloc()仅仅是一个函数,没有初始化的过程,需要编码人员手动初始化。

5、分配失败

malloc分配内存失败时返回NULL,new内存分配失败时,有两种情况:

1)抛出bad_alloc异常来报告分配失败;

2)返回空指针,而不会抛出异常。

 首先,c++是在c语言的基础之上发展而来,而且c++发明时是想尽可能的与c语言兼容。而c语言是一种没有异常机制的语言,所以c++应该会提供一种没有异常机制的new分配内存失败报告机制;(确实是如此,早期的c++还没有加入异常机制),其次在返回空指针的实现过程中,c++采用的是malloc/calloc 等分配内存的函数,该类函数不会抛出异常,但是在分配内存失败时会返回“空指针”。最后,对于标准的c++,有着比较完善的异常处理机制,所以对于出现异常时,会抛出响应的异常。对于new分配失败时,系统会抛出bad_alloc异常。

所以具体是那种情况,看编译器对标准c++的支持情况。

6、自定义类型(类等)

对于自定义类型,new会先调用operator new函数,申请足够的内存(通常底层使用malloc实现)。然后调用类型的构造函数,初始化成员变量,最后返回自定义类型指针。delete先调用析构函数,然后调用operator delete函数释放内存(通常底层使用free实现)。

malloc/free是库函数,只能动态的申请和释放内存,无法强制要求其做自定义类型对象构造和析构工作。

7、重载

C++允许重载new/delete操作符,特别的,布局new的就不需要为对象分配内存,而是指定了一个地址作为内存起始区域,new在这段内存上为对象调用构造函数完成初始化工作,并返回此地址。而malloc不允许重载。

8、 内存区域

new操作符从自由存储区(free store)上为对象动态分配内存空间,而malloc函数从堆上动态分配内存。自由存储区是C++基于new操作符的一个抽象概念,凡是通过new操作符进行内存申请,该内存即为自由存储区。而堆是操作系统中的术语,是操作系统所维护的一块特殊内存,用于程序的内存动态分配,C语言使用malloc从堆上分配内存,使用free释放已分配的对应内存。自由存储区不等于堆,如上所述,布局new就可以不位于堆中。

自由存储区是否可以是堆?这取决于operate new 的实现细节。自由存储区不仅仅可以是堆,还可以是静态存储区,这取决于operate new 在哪里为对象分配内存。

 

十个区别:

特征new/deletemalloc/free
分配内存的位置 自由存储区
内存分配成功返回 完整类型指针 void*
内存分配失败返回值 默认抛出异常 返回NULL
分配内存的大小 由编译器根据类型计算得出 必须显式指定字节数
处理数组 有处理数组的new版本new[] 需要用户计算数组的大小后进行内存分配
已分配内存的扩充 无法直观地处理 使用realloc简单完成
是否相互调用 可以,看具体的operator new/delete实现 不可调用new
分配内存时内存不足 客户能够指定处理函数或重新制定分配器 无法通过用户代码进行处理
函数重载 允许 不允许
构造函数与析构函数 调用 不调用

 

a)malloc 可以通过realloc重新分配内存大小

void *raealloc(void *ptr,size_t size)

void *ptr表示之前malloc分配内存空间的首地址,size是新的内存大小。注意新分配大小不能比malloc所申请的小,否则会造成数据丢失。

b)在使用delete后,注意将指针置为NULL,否则会形成悬垂指针(指针所指内存已被释放,仍指向该内存),造成错误

这是因为delete后,虽然内存释放的了,但是指针所指向的地址仍未改变,只是内容被清除。后续代码任然可以调用。

c)new与delete,new a[ ]与delete [ ] a成对使用,除了(当new的内存空间分配给没有显式定义给、析构函数类的指针,可以使用delete[ ]释放)

 

 PS:在C++中,内存区分为5个区,分别是堆、栈、自由存储区、全局/静态存储区、常量存储区;

 在C中,C内存区分为堆、栈、全局/静态存储区、常量存储区;

posted @ 2018-09-14 02:27  Ethan_zhang  阅读(638)  评论(0编辑  收藏  举报