malloc/free 和new/delete区别

(1)、malloc和new都是在堆上开辟内存的,它们都可用于申请动态内存和释放内存。malloc开辟内存永远是通过free释放的;而new是单个元素内存,用delete,如果是new[]数组,则用delete[]来释放内存。

另外, malloc不可以重载,new可以重载

(2)、malloc只负责开辟内存,没有初始化功能,需要用户初始化;new不但开辟内存,还可以进行初始化,

eg: int* p=new int(10);表示在堆上开辟了一个4字节的内存,初始值是10,

      int* p=new int[10]();表示在堆上开辟了一个10个整型元素的数组,初始值为0

(3)、malloc与free是C++/C语言的标准库函数,开辟内存需要传入字节数,

      eg: int *p=( int *)malloc(sizeof(int)*10) ;  malloc在申请内存的时候,必须要提供申请的长度,而且返回的指针是void*型,表示分配的堆内存的起始地址,必须要强转成需要的类型。

      new/delete是C++的运算符。开辟内存需要指定类型,返回指定类型的地址,因此不需要进行强转。

另外,函数有函数的调用,依赖于库,但是运算符是语言固有的属性,如+-*/,编译器可以进行翻译;

(4)、malloc开辟内存失败会返回NULL,不会抛出异常;而new内存开辟失败会抛出bad_alloc类型的异常,需要捕获异常才能判断内存开辟成失败;

你无法重新定义malloc失败时的默认行为(返回null),但你可以重定义new失败时的默认行为,比如不让它抛出异常。

(5)、malloc 开辟内存只有一种方式,new有四种,分别是:普通的new(开辟失败抛出bad_alloc异常),nothrow版本的new(不会抛出异常,开辟失败会返回NULL),const new(堆上开辟常量内存), 定位new(并没有真正的开辟内存,而是在已经开辟的内存上开辟内存)eg:int* p=new int[128];   int* q=new (p) int[4];

(6)(能否调用构造函数)new运算符其实是operator new函数的调用,底层调用也是通过malloc来开辟内存的,new比malloc多的就是初始化功能,对于类类型来说,所谓初始化就是调用相应的构造函数。

       C++中new/delete能调用构造函数和析构函数,而malloc/free不能,只是单纯的申请内存空间;

       对于非内部数据类型的对象而言,光用maloc/free无法满足动态对象的要求。对象在创建的同时要自动执行构造函数,对象在消毁之前要自动执行析构函数。由于malloc/free是库函数而不是运算符,不在编译器控制权限之内,不能够把执行构造函数和析构函数的任务强加于malloc/free。因此C++语言需要一个能完成动态内存分配和初始化工作的运算符new,以及一个能完成清理与释放内存工作的运算符delete。我们不要企图用malloc/free来完成动态对象的内存管理,应该用new/delete。

        由于内部数据类型的“对象”没有构造与析构的过程,对它们而言malloc/free和new/delete是等价的。

  (7)既然new/delete的功能完全覆盖了malloc/free,为什么C++不把malloc/free淘汰出局呢?

这是因为C++程序经常要调用C函数,而C程序只能用malloc/free管理动态内存。如果用free释放“new创建的动态对象”,那么该对象因无法执行析构函数而可能导致程序出错。如果用delete释放“malloc申请的动态内存”,虽然理论上程序不会出错,但是该程序的可读性很差。所以new/delete必须配对使用,malloc/free也一样。

猜你喜欢

转载自blog.csdn.net/ymy_mine/article/details/81179584