文章目录
- 一、new/delete是什么?
- 1.new
- 2.delete
- 二、new/delete怎么用?
- 1.new
- 2.delete
- 3.new[]
- 4.[]delete
- 三、new/delete为什么?
- 1.为什么有operator new/operator delete?
- 2.为什么要匹配使用new和delete?
new/delete测试环境:visual studio2019社区版
一、new/delete是什么?
在C++编程中,new 和 delete 是用于动态分配和释放内存的操作符,简单来讲c++申请空间和释放空间的最好办法就是:new 和 delete,由于是操作符,所以使用new 和 delete不需要包头文件。
1.new
new:new 操作符用于动态分配内存来创建一个对象或一块内存区域,并返回一个指向分配内存的指针。它用于在堆上分配内存,以便在程序的任何地方使用,而不仅仅在栈上。通常用于创建动态对象,如类实例。
例如,创建一个整数对象并分配内存可以这样做:
int* myInt = new int;
这将在堆上分配一个整数大小的内存块,并返回一个指向该内存的指针。
2.delete
delete:delete 操作符用于释放先前由 new 分配的内存,以防止内存泄漏。它删除之前分配的内存,并将指针置为空,以防止访问已释放的内存。
例如,删除之前分配的整数对象内存可以这样做:
delete myInt;
myInt = nullptr; // 将指针置为空,以避免野指针
注意:在使用 new 分配内存后,务必使用 delete 来释放内存,以避免内存泄漏。否则,分配的内存将一直保留在堆上,直到程序终止,这可能导致内存资源耗尽。最好的做法是使用智能指针。
二、new/delete怎么用?
1.new
new会在堆上申请一片空间,并且会返回这片空间的地址,所以要用指针类型接收,如果申请空间失败,new会抛出异常值
模板:Type* T=new Type
为内置类型申请空间:
int* mytype = new int
new内置类型注意:
1.new不会对内置类型申请的空间初始化,用户需要自己初始化。
2.new内置类型是在堆上申请空间,系统不会自己释放空间,所以需要用户使用delete手动释放空间。
为自定义类型申请空间
class A
{
public:A(int a=1){_a=a;}
private:int _a;
};
//newA* p1 = new A;
new自定义类型注意:
1.new会对自定义类型申请的空间进行特殊处理,在new的过程中会调用自定义类型的构造函数。
2.new自定义类型是在堆上申请空间,系统不会自己释放空间,所以需要用户使用delete手动释放空间。
ps:查看new调用自定义类型构造的现象
2.delete
和new配套使用,释放new从堆上开辟的空间
//Type* T=new Type
模板:delete T;
*为内置类型释放空间
//int* mytype = new int;
delete mytype;
delete内置类型注意:
1.此时的delete行为和free()一致,单纯释放new开的空间。此时讲deletet替换成free也不会有问题
为自定义类型释放空间
class A
{
public:A(int a=1){_a=a;}
private:int _a;
};A* p1 = new A;//deletedelete p1;
delete内置类型注意:
1.此时的delete不仅仅会释放new的空间,还会调用自定义类型的析构函数,先后过程为先调用析构函数,再释放空间
ps delete调用自定义类型析构的现象
3.new[]
c++申请多个连续对象使用new[],其中[]中可指定申请对象的个数,如果申请失败,则会抛出异常值。
模板:Type* T = new Type[n];//申请n个对象的Type数组
为内置类型申请空间
int* mytype = new int[10];
new[]内置类型注意:
1.new不会对内置类型申请的空间初始化,用户需要自己初始化。
2.new内置类型是在堆上申请空间,系统不会自己释放空间,所以需要用户使用delete[]手动释放空间。
ps:可在定义时同时初始化,
为自定义类型申请空间
class A
{
public:A(int a=1){_a=a;}
private:int _a;
};A* p1 = new A[2]{0,1};
new[]自定义类型注意:
1.new[n]会对自定义类型申请的空间进行特殊处理,在new的过程中会调用n次自定义类型的构造函数。
2.new[]自定义类型是在堆上申请空间,系统不会自己释放空间,所以需要用户使用[]delete手动释放空间。
ps:new[n]调用构造函数现象
4.[]delete
delete[]功能为释放由new[]申请的连续空间。
为内置类型释放空间
int* mytype = new int[10];
delete []mytype;
[]delete释放内置类型空间注意:
1.不需要在[]delete的[]中指定对象个数
2.[]delete务必和new[]配套使用否则容易出现未定义的错误
为自定义类型释放空间
A* p1 = new A[2]{0,1};
delete []p1;
[]delete释放自定义类型空间注意:
1.不需要在[]delete的[]中指定对象个数
2.[]delete务必和new[]配套使用否则容易出现未定义的错误
3.在使用[]delete中会调用对象的析构函数,再释放空间,先后是:先调用析构再释放空间
ps:[]delete调用析构函数的现象
三、new/delete为什么?
1.为什么有operator new/operator delete?
在前面的汇编代码中我们发现new和delete都会调用operator new/operator delete
(在vs2019中delete对operator delete调用隐藏了起来),那么这是为什么呢?
在C++中,operator new和operator delete是用于动态内存管理的特殊函数,这两个函数不是重载函数,是c++开发者定义的两个特殊的全局函数。它们允许程序员自定义内存分配和释放的行为,以满足特定的需求。这两个操作符通常与关键字new和delete一起使用,在汇编过程中new和delete都会调用operator new/operator delete来实现开辟空间和释放空间。
实际上operator new和operator delete这两个函数的底层还是用c中用来申请和释放空间的函数“malloc”和f“ree()”实现的,operator new和operator delete是“malloc”和“free”的高级封装版本,完善了对错误的处理。c++创造operator new和operator delete是为了更好的为c++"面向对象“的概念服务,因为“malloc”和“free”对异常的处理不适合c++理念,一句话讲,就是c中原始的“malloc”和“free”不好用,c++把它们封装成了operator new和operator delete.
2.为什么要匹配使用new和delete?
为什么需要区分使用new和delete,new[]和delete[]?
1.正确的内存释放: 使用new和delete,new[]和delete[]的配对使用是为了确保正确的内存释放。数组对象通常需要更复杂的析构和释放过程,因此需要使用new[]和delete[]。
2.调用正确的析构函数: 使用new[]分配数组时,C++会在每个数组元素上调用构造函数,而使用delete[]释放数组时,会在每个数组元素上调用析构函数。这样确保了每个对象的构造和析构过程都被正确执行。
3.避免未定义行为: 使用new[]和delete[]配对使用可以避免因未定义的内存释放行为而引起的问题。在释放数组时,系统需要知道数组的大小,以便逐个调用对象的析构函数。