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对于内置类型开辟空间,功能都差不多。

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对于自定义类型开辟空间的不同之处。

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调用的构造函数和析构函数。

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

相关推荐

  1. C++动态

    2024-07-17 21:56:04       44 阅读
  2. C# 分配管理

    2024-07-17 21:56:04       53 阅读
  3. c++ 动态分配

    2024-07-17 21:56:04       33 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-17 21:56:04       53 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-17 21:56:04       56 阅读
  3. 在Django里面运行非项目文件

    2024-07-17 21:56:04       46 阅读
  4. Python语言-面向对象

    2024-07-17 21:56:04       57 阅读

热门阅读

  1. lightgbm

    lightgbm

    2024-07-17 21:56:04      24 阅读
  2. ansible报错--‘when‘ is not a valid attribute for a Play

    2024-07-17 21:56:04       23 阅读
  3. [C/C++入门][for]24、菲波那契数列

    2024-07-17 21:56:04       22 阅读
  4. Linux C++ 060-设计模式之单例模式

    2024-07-17 21:56:04       19 阅读
  5. 使用axios实现vue web前端无痕刷新

    2024-07-17 21:56:04       20 阅读
  6. 调试和测试PER语言代码的最佳实践

    2024-07-17 21:56:04       19 阅读
  7. 不同行业的私域引流策略有何差异?

    2024-07-17 21:56:04       17 阅读
  8. 算法训练营day72

    2024-07-17 21:56:04       19 阅读
  9. 第二章:pod-运行于kubernetes中的容器

    2024-07-17 21:56:04       15 阅读
  10. 昇思25天学习打卡营第25天|SSD目标检测

    2024-07-17 21:56:04       17 阅读
  11. 怎么选择适合自己的酱香白酒?

    2024-07-17 21:56:04       17 阅读
  12. UDP协议

    UDP协议

    2024-07-17 21:56:04      20 阅读
  13. D365 Fraud Protection Account Protection部署方案

    2024-07-17 21:56:04       22 阅读