new与malloc的区别
一,malloc与free函数
1,malloc()函数
函数原型:void *malloc(int size)
函数功能:malloc的全称是memory allocation,中文是动态内存分配。malloc向系统申请size个字节大小的内存空间,函数的返回值类型是void *类型。void *表示未确定类型的指针,C/C++规定void *类型指针可以转换成任何其他类型的指针。void *表示未确定类型的指针,是说申请内存空间时,还不知道用户要用这块内存空间存储什么类型的数据。
2,free()函数
函数原型:void free(void *p)
函数功能:释放掉之前使用malloc分配的内存空间。
3,注意事项
a,申请内存空间之后,必须检查是否分配成功。
b,当不需要申请的内存时,记得及时释放掉。释放后应该把指向这块内存的指针设置为NULL,防止后面的程序不小心用到它。
c,malloc与free应该配对使用。
4,malloc是从什么地方获取的内存空间?
从堆里获取的内存空间,操作系统有一个记录空闲内存地址的链表。当系统收到内存申请时,就会遍历该链表,寻找第一个空间大于所申请的内存的节点,然后把这个节点从链表中删除,并将该节点的内存分配给申请者。
二,new运算符
1,使用new动态分配内存
int *p = new int; //动态分配内存
int *p = new int(10); //分配内存,并对内存进行初始化
2,使用delete释放分配的内存
delete p; //释放单个对象
delete [] p; //释放对象数组
3,new分配失败
new分配失败时,会抛出bad_alloc异常
4,注意事项
new与delete、new []与delete []要配对使用,不然可能会导致内存泄露。使用delete的最大问题在于:即将被删除的内存里有多少个对象?这个问题的答案决定了有多少个析构函数必须被调用。上面的这个问题也可理解为:即将被删除的那个指针,所指的是单一对象还是对象数组。如果使用delete时不加中括号,此时delete便认定要删除的是一个单独的对象,如果使用delete时加上中括号,此时delete便认定要删除的是一个对象数组
三,new与malloc的区别
1,是否需要指定要分配的内存的大小
new返回指定类型的指针,并自动计算大小,例如:下面的new返回的指针类型为int *,分配的内存空间的大小为sizeof(int)。
int *p = new int;
malloc则必须由我们计算分配的字节数,并且在返回后还要把指针强制转换为实际的类型
int *p = (int *)malloc(sizeof(int));
2,是否会对分配的内存进行初始化
malloc只负责分配内存,并不能对分配的内存进行初始化,但是new可以对分配的内存进行初始化。
#include <iostream>
#include <stdlib.h>
using namespace std;
class A{
public:
A(){cout<<"A"<<endl;}
};
int main(){
A *p1 = new A;
A *p2 = (A *)malloc(sizeof(A));
return 0;
}
输出结果
A
Process returned 0 (0x0) execution time : 0.006 s
Press any key to continue.
程序分析
由程序的输出结果可以看出,new会分配内存,并调用类的构造函数创建对象,而malloc只是分配内存,不调用类的构造函数初始化对象。
四,有了malloc/free为什么还要使用new/delete?
1,对于自定义的class类型,malloc无法满足动态创建对象的要求。对象在创建的同时要自动执行构造函数,对象的生命周期结束时要自动调用析构函数。由于malloc/free是库函数而不是运算符,不在编译器的控制权限之内,不够把执行构造函数与析构函数的任务强加于malloc/free。因此,C++提供了new运算符来完成内存的动态分配与初始化工作,delete来完成内存的清除与释放工作。
2,既然new/delete的功能已经覆盖malloc/free,C++为什么不淘汰掉malloc/free?这是因为C++程序要经常调用C函数,而C函数只能使用malloc/free来动态管理内存。
3,如果使用free释放使用new创建的对象,那么该对象因无法执行析构函数而可能导致程序出错。如果使用delete释放malloc分配的内存,结果也会导致程序出错,所以new/delete,malloc/free应该配对使用。