在C语言中使用malloc、calloc、realloc、free管理内存,在C++中引入了new和delete来管理内存。
new和delete的使用
对于内置类型的运用
// 动态申请一个int类型的空间
int* p1 = new int;
//动态申请一个int类型的空间并初始化为1
int* p2 = new int(1);
// 动态申请10个int类型的空间
int* p3 = new int[10];
delete p1;
delete p2;
delete [] p3;
对于自定义类型的运用
class A
{
public:
A(int a = 1;)
:_a(a);
{}
~A()
{}
private:
int _a;
};
int main()
{
// malloc和new最大区别就是new会调用构造函数,free和delete的最大区别就是delete会调用析构函数。
A* p1 = (A*)malloc(sizeof(A));
// p1是一个整型指针,存储在栈区,p1存的内容是一个指针,该指针指向在堆区开辟的内容。
A* p2 = new A(1);
free(p1);
delete p2;
return 0;
}
operator new 和 operator delete函数
在功能上:operator new 和 operator delete是介于malloc和free之间的。
当使用malloc申请内存时,如申请失败会返回NULL,而operator new 在申请失败时会抛异常。
而使用free时也会面临释放多了和少了的错误,那么operator delete也会抛异常。
总而言之:这两个全局函数都是通过malloc和free来申请和释放空间的,只是多了抛异常。
new和delete使用原理
如果申请的是内置类型,那么基本相似,只是new和delete在malloc和free的基础上加上处理异常。
如果申请的是自定义类型:
- new:1、调用operator new申请内存;2、调用构造函数
- delete:1、先调用析构函数,清理资源;2、调用operator delete释放内存。
定位new表达式(placement-new)
在已经分配的内存上调用构造函数初始化一个对象。
class A
{
public:
A(int a = 1;)
:_a(a);
{}
~A()
{}
private:
int _a;
};
int main()
{
A* p1 = (A*)malloc(sizeof(A)); // 这里只是申请了空间,并没有调用构造函数
new(p1)A;
p1->~A();
free(p1);
A* p2 = (A*)malloc(sizeof(A));
new(p2)A(10);
p2->~A();
operator delete(p2);
return 0;
}
malloc、free和new、delete的区别
- malloc、free是函数,new、delete是操作符
- 申请自定义类型时,new、delete会调用构造函数和析构函数,malloc只是申请内存。
- malloc申请内存需要对void*强转,并且需要对申请的内存大小计算,new不需要
- mallo申请内存失败会返回NULL,new会抛出异常。
内存泄漏
申请了内存却没有进行释放,会失去对内存的控制。导致响应越来越慢。