在C++中,申请动态内存与释放动态内存用new/delete 与 malloc/free都可以,new/malloc申请动态内存,操作系统无法自动回收,需要对应的delete/free释放空间。那他们之间的区别在哪?
区别
1.
malloc/free 是c语言中的库函数,需要头文件支持;而new/delete 是c++中的关键字
2.
使用new操作符时编译器会根据类型信息自行计算所需要的内存,而malloc需要显式指出所需内存的尺寸
int *p = new int[2];
int *q = (int *)malloc(2*sizeof(int));
3.
malloc内存分配成功时,返回的是void*,需要转换成所需要的类型
new内存分配成功时,返回的是对象类型的指针,类型严格与对象匹配,无须进行类型转换,故new是符合类型安全性的操作符
free释放内存的时候需要的是void* 类型的参数
delete释放内存的时候需要使用具体类型的指针
4
new操作符在分配失败的时候会抛出bac_alloc异常
malloc在分配内存失败时返回NULL
5.
new操作符从自由存储区(free store)上为对象动态分配内存空间,允许重载new/delete操作符
malloc函数从堆上动态分配内存,malloc不允许被重载
从技术上来说,堆(heap)是C语言和操作系统的术语。堆是操作系统所维护的一块特殊内存,它提供了动态分配的功能,当运行程序调用malloc()时就会从中分配,稍后调用free可把内存交还。而自由存储是C++中通过new和delete动态分配和释放对象的抽象概念,通过new来申请的内存区域可称为自由存储区。基本上,所有的C++编译器默认使用堆来实现自由存储,也即是缺省的全局运算符new和delete也许会按照malloc和free的方式来被实现,这时藉由new运算符分配的对象,说它在堆上也对,说它在自由存储区上也正确。但程序员也可以通过重载操作符,改用其他内存来实现自由存储,例如全局变量做的对象池,这时自由存储区就区别于堆了。
6.
new会先调用operator new函数,申请足够的内存(通常底层使用malloc实现)。然后调用类型的构造函数,初始化成员变量,最后返回自定义类型指针。delete先调用析构函数,然后调用operator delete函数释放内存(通常底层使用free实现)。
malloc/free是库函数,只能动态的申请和释放内存,无法强制要求其做自定义类型对象构造和析构工作。
也就是说
new能够触发构造函数的调用,malloc不行出发构造函数的调用,它只能分配所需要的空间。delete可以出发析构函数的调用,但是free仅归还之前申请的内存空间
注意事项:
delete和free被调用后,内存不会立即回收,指针也不会指向空,delete或free仅仅是告诉操作系统,这一块内存被释放了,可以用作其他用途。但是由于没有重新对这块内存进行写操作,所以内存中的变量数值并没有发生变化,这时候就会出现野指针的情况。因此,释放完内存后,应该把指针指向NULL。
运行结果