【C++】new和delete深度解析

【C++】new和delete深度解析_第1张图片

文章目录

  • 一、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;
}//new
	A* p1 = new A;

new自定义类型注意:

1.new会对自定义类型申请的空间进行特殊处理,在new的过程中会调用自定义类型的构造函数。
2.new自定义类型是在堆上申请空间,系统不会自己释放空间,所以需要用户使用delete手动释放空间。

ps:查看new调用自定义类型构造的现象
【C++】new和delete深度解析_第2张图片

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;
	//delete
	delete p1;

delete内置类型注意:

1.此时的delete不仅仅会释放new的空间,还会调用自定义类型的析构函数,先后过程为先调用析构函数,再释放空间
ps delete调用自定义类型析构的现象
【C++】new和delete深度解析_第3张图片

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]{01};

new[]自定义类型注意:

1.new[n]会对自定义类型申请的空间进行特殊处理,在new的过程中会调用n次自定义类型的构造函数。
2.new[]自定义类型是在堆上申请空间,系统不会自己释放空间,所以需要用户使用[]delete手动释放空间。

ps:new[n]调用构造函数现象
【C++】new和delete深度解析_第4张图片

4.[]delete

delete[]功能为释放由new[]申请的连续空间。

为内置类型释放空间

int* mytype = new int[10];
delete []mytype;

[]delete释放内置类型空间注意:

1.不需要在[]delete的[]中指定对象个数
2.[]delete务必和new[]配套使用否则容易出现未定义的错误

为自定义类型释放空间

A* p1 = new A[2]{01};
delete []p1;

[]delete释放自定义类型空间注意:

1.不需要在[]delete的[]中指定对象个数
2.[]delete务必和new[]配套使用否则容易出现未定义的错误
3.在使用[]delete中会调用对象的析构函数,再释放空间,先后是:先调用析构再释放空间

ps:[]delete调用析构函数的现象
【C++】new和delete深度解析_第5张图片


三、new/delete为什么?

1.为什么有operator new/operator delete?

在前面的汇编代码中我们发现new和delete都会调用operator new/operator delete
(在vs2019中delete对operator delete调用隐藏了起来),那么这是为什么呢?

【C++】new和delete深度解析_第6张图片

在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.
【C++】new和delete深度解析_第7张图片


2.为什么要匹配使用new和delete?

为什么需要区分使用new和delete,new[]和delete[]?

1.正确的内存释放: 使用new和delete,new[]和delete[]的配对使用是为了确保正确的内存释放。数组对象通常需要更复杂的析构和释放过程,因此需要使用new[]和delete[]。
2.调用正确的析构函数: 使用new[]分配数组时,C++会在每个数组元素上调用构造函数,而使用delete[]释放数组时,会在每个数组元素上调用析构函数。这样确保了每个对象的构造和析构过程都被正确执行。
3.避免未定义行为: 使用new[]和delete[]配对使用可以避免因未定义的内存释放行为而引起的问题。在释放数组时,系统需要知道数组的大小,以便逐个调用对象的析构函数。

你可能感兴趣的:(c++,开发语言,c语言,汇编)