new/delete和malloc/free的区别详解

目录

 

new/delete的用法:

malloc和free的用法:

new和malloc的区别:

free和delete用法:


new/delete和malloc/free的区别详解

       在软件开发中,常常需要动态地分配和撤销内存空间,在C语言中利用库函数malloc和free来分配和撤销内存空间。c++

提供了较简单而功能较强的运算符new和delete来取代malloc和free函数。

       new和delete是运算符,不是函数因此执行效率高。虽然为了与c语言兼容,c++仍保留malloc和free,但是不建议使用。

new/delete的用法:

new int ;      //开辟一个存放整数的储存空间,返回一个指向该储存空间的地址
new int(10);   //开辟一个存放整数的储存空间,并指定该函数的初始值为10,返回一个指向该空间的地址
new char[10];  //开辟一个字符数组(包括10个元素的空间),返回元素的首地址
new int [5][4];//开辟一个存放二维整型数组(5*4)的空间,返回首元素的地址
float *p = new float(3.14159);
//开辟一个存放单精度浮点的空间,并指定该函数的初始值为3.14159,将返回的该空间的地址赋给指针变量p

格式:

new 类型  [ 初值 ]

用new分配数组空间时不能指定初始值。如果由于内存不足等原因而无法正常访问空间,则new会返回一个空指针,可以通过改指针的值判断空间是否分配成功。

delete 指针变量(对变量)

delete [ ] 指针变量 (对数组)

 float *p = new float(3.14159);——————delete p;

new char[10];—————————————delete  [ ]  p//指针变量前加一对括号表示对数组空间的操作

malloc和free的用法:

函数的原型:

void *malloc(size_t size);
void free(void *pointer);

示例代码如下:

int *p=(int *)malloc(100);                   //指向整型的指针p指向一个大小为100字节的内存的地址
int *p=(int *)malloc(25*sizeof(int));       //指向整型的指针p指向一个25个int整型空间的地址

malloc特点:

  因为malloc()函数的返回值类型为void *,所以需要在函数前面进行相应的强制类型转换。

这个函数向内存申请一个连续可用的空间,并返回这块空间的指针。

————如果开辟成功,则返回一个指向开辟好空间的指针

————如果开辟失败,则返回一个NULL指针,因此malloc的返回值一定要检查

————返回值的类型是void*(指针) ,所以malloc不知道开辟空间的类型

————malloc分配的内存大小至少为size参数所指的字节数

free特点:

malloc 与 free函数是配对的,如果是申请后不释放就是内存泄漏

————如果参数ptr指向的空间不是动态开辟的,那么free函数行为是未定义的

————如果参数是NULL,free函数什么都不做

更多介绍:

malloc,calloc,realloc ,free 的介绍,区别

new和malloc的区别:

属性:

  new/delete是C++关键字,需要编译器支持。

       malloc/free是库函数,需要头文件支持c。

参数:

  使用new操作符申请内存分配时无须指定内存块的大小,编译器会根据类型信息自行计算。而malloc则需要显式地指出所需内存的尺寸。

返回类型:

  new操作符内存分配成功时,返回的是对象类型的指针,类型严格与对象匹配,无须进行类型转换,故new是符合类型安全性的操作符。

       而malloc内存分配成功则是返回void * ,需要通过强制类型转换将void*指针转换成我们需要的类型。

分配失败:

  new内存分配失败时,会抛出bac_alloc异常。malloc分配内存失败时返回NULL。

自定义类型:

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

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

重载:

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

内存区域:

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

参考文章(真的很详细)

http://www.cnblogs.com/QG-whz/p/5140930.html

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

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

free和delete用法:

首先free对应的是malloc;delete对应的是new;free用来释放malloc出来动态内存,delete用来释放new出来的动态内存空间。

对应使用,对应使用,对应使用!否则可能出现内存泄漏或崩溃的可能!

应用的区别为:

  1.

float *p = new float(3.14159);——————delete p;

new char[10];—————————————delete  [ ]  p

注意[ ]的作用说明释放的是一个数组的内存,如果delete p则只是释放的p[0],其余9个char的内存没有释放;

这是因为当指明为[]的时候,编译器实际上是做了一个循环来释放这个数组的所有内存。

  2.

在使用malloc和free来处理动态内存的时候,仅仅是释放了这个对象所占的内存,而不会调用这个对象的析构函数;

使用new和delete就可以既释放对象的内存的同时,调用这个对象的析构函数

共同之处:

  它们都是只把指针所指向的内存释放掉了,并没有把指针本身干掉。在free和delete之后,都需要把指向清理内存的指针置为空,即p=NULL

否则指针指向的内存空间虽然释放了,但是指针p的值还是记录的那块地址,该地址对应的内存是垃圾,p就成了“野指针”。

理解:

  即free和delete之后,是把从堆中获取的内存释放,这部分内存现在可以分配给其它使用。但是栈中的指针本身依然存在,并仍然指向该部分内存。

        如果不把指针设置为NULL。后面仍然去调用该指针,可以获得这部分内存中的值。但是这部分内存中的值是不确定的,有可能已经被其它程序调用,即“野指针”。

        如果只是单纯的把指针设置为NULL,没有调用free和delete会导致内存泄露。即从指针判断的话,已经无法访问内存。但是由于没有调用free和delete,导致系统以为这部分内存依然在使用,程序执行过程中无法分配给其它部分,导致内存浪费。

     如果再次释放p指向的空间,编译器就会报错,因为释放一个已经被释放过的空间是不合法的。而将其置为NULL之后再重复释放就不会产生问题,因为delete一个0指针是安全的。

指针和动态申请的内存空间总结如下:

  1.

           指针置空,并不表示它指示的动态内存会自动释放;

  2.

      动态内存释放掉了,指针本身依然存在,并仍然指向该部分内存。

           动态内存释放掉了,并且调用了析构函数,并不表示指针会消亡或者自动变成了NULL。

猜你喜欢

转载自blog.csdn.net/W_J_F_/article/details/82633727