C++动态内存的管理

今天来分享C++动态内存管理相关知识,闲言勿谈,直接上干货。

1. 动态内存的开辟和销毁(new和delete)

(1)前置知识:我们知道c语言有malloc和calloc和realloc三个函数可以进行动态的开辟内存,那么它们有什么区别呢?首先是malloc,malloc表示直接在堆上动态开辟内存空间,返回void*,而calloc不仅可以直接在堆上动态开辟内存空间,还会把开辟空间的内容初始化为0,calloc返回的也是void*,realloc是在原有的空间的基础上进行扩容,也是返回void*.c语言虽然有三个动态开辟内存的函数,但在某些场景下不适用,同时用起来也比较麻烦,所以c++引入了一个new操作符进行动态开辟内存,delete操作符进行销毁开辟的内存,那么接下来我们看看new的用法吧。

(2)new和delete用法

new和delete操作符对内置类型进行开辟空间

new和malloc对于内置类型开辟空间,功能都差不多。

cpp 复制代码
int main()
{
	//表示在堆上申请一个int空间
	int* p1 = new int;
	delete p1;

	//表示在堆上申请一个int空间并初始化为4
	int* p2 = new int(4);
	delete p2;

	//表示在堆上申请3个int空间
	int* p3 = new int[3];
	delete[] p3;

	return 0;
}

new和delete操作符对自定义类型进行开辟空间

我们来看看new和malloc对于自定义类型开辟空间的不同之处。

cpp 复制代码
class A
{
public:
	A(int a = 0)
		: _a(a)
	{
		cout << "A():" << this << endl;
	}
	~A()
	{
		cout << "~A():" << this << endl;
	}
private:
	int _a;
};

int main()
{
	A* p1 = (A*)malloc(sizeof(A));

	A* p2 = new A;

	free(p1);
	delete p2;
	return 0;
}

我们来看看这个代码运行的结果

咋出现了调用构造函数和析构函数呢?是谁调用的呢?

我们把malloc和free的函数进行注释掉,如果还调用构造函数和析构函数,那么证明是new和delete调用的构造函数和析构函数。

cpp 复制代码
class A
{
public:
	A(int a = 0)
		: _a(a)
	{
		cout << "A():" << this << endl;
	}
	~A()
	{
		cout << "~A():" << this << endl;
	}
private:
	int _a;
};

int main()
{
	/*A* p1 = (A*)malloc(sizeof(A));*/

	A* p2 = new A;

	//free(p1);
	delete p2;
	return 0;
}

还是调用了构造函数和析构函数,现在我们就清楚了malloc函数和new操作符,free函数和delete操作符之间的区别是,new开辟空间是会调用构造函数进行初始化,delete在释放空间是会调用析构函数对对象中的资源进行清理。

(2)operator new函数和operator delete函数

我们先来看看c++标准库里面是如何实现operator new和operator delete函数的。

我们可以看到operator new和operator delete是依靠malloc和free函数实现的,该函数实际通过malloc来申请空间,当malloc申请空间成功时直接返回;申请空间失败,尝试执行空间不足应对措施,如果改应对措施用户设置了,则继续申请,否则抛异常。

new和delete实现的原理

(1)对于内置类型,new和malloc功能相似,delete和free功能相似。

(1)对于自定义类型

new不仅调用operator new函数开辟空间还会调用构造函数。

delete不仅会调用operator delete函数释放空间,还会调用析构函数完成对对象资源的清理工作

总结:

1.共同点:malloc和new都是在堆上开辟空间,都需要手动释放开辟的空间

2.不同点:malloc和free是函数,new和delete是操作符(概念性质不同)

malloc开辟空间是要传需要开辟的字节数,返回的是void*;而new后跟申请对象的类型,返回的是申

请对象的类型的指针

new会调用构造函数,开辟失败会抛异常,malloc开辟失败会返回0

相关推荐
啊我不会诶5 分钟前
篮球杯软件赛国赛C/C++ 大学 B 组补题
c语言·c++
l1t8 分钟前
DeepSeek辅助实现的DuckDB copy to自定义函数
数据库·c++·人工智能
南瓜胖胖11 分钟前
【R语言编程——数据调用】
开发语言·r语言
henreash15 分钟前
C# dll版本冲突解决方案
开发语言·c#
黎䪽圓36 分钟前
【Java多线程从青铜到王者】单例设计模式(八)
java·开发语言·设计模式
摸鱼仙人~1 小时前
Redux Toolkit 快速入门指南:createSlice、configureStore、useSelector、useDispatch 全面解析
开发语言·javascript·ecmascript
onlooker66661 小时前
Go 语言底层(四) : 深入 Context 上下文
开发语言·数据库·golang
Bardb1 小时前
01__C++入门
c++·qt