首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【C++课程学习】:new和delete为什么要配套使用,new,delete和malloc,free的比较

【C++课程学习】:new和delete为什么要配套使用,new,delete和malloc,free的比较

作者头像
用户11396661
发布2024-12-09 15:17:45
发布2024-12-09 15:17:45
25200
代码可运行
举报
文章被收录于专栏:C++开发C++开发
运行总次数:0
代码可运行

🎡1.new,delete和malloc,free的区别:

⌚️相同点:

new,delete和malloc,free都是对动态内存进行管理的。动态内存是位于堆上的,不会随着函数生命周期的结束而结束,正因为这样,所以才要用户主动的进行空间释放。不然就会造成空间泄露。

●空间泄露:不是物理层面的消失,而是我们失去对某块空间的控制。

危害:长期运行的程序出现内存泄漏会使反应越来越慢,最终卡死。

⌚️不同点:

🏆1.new,delete是操作符,malloc,free是函数。

🥊操作符和函数的区别: 1.操作符在编译的过程就进行了替代,而函数要在运行中进行调用。 2.操作符不需要要有头文件,由编译器实习,而函数必须要有具体实现。

🏆2.是否能进行初始化:

malloc不可以进行初始化。new可以进行初始化,也可以不进行初始化。


🏆3.是否需要进行类型转化:

malloc申请的空间是void*,所以要进行类型转化,new申请的空间里面有类型,不需要进行转化。


🏆4.空间大小的计算:

malloc要明确申请空间的大小(单位:字节),但是new只要明确申请几个就可以了,申请多个时,在类型后面加[个数]。


🏆5.是否主动调用构造函数和析构函数:

在处理自定义类型的时候,new会调用构造函数,delete会主动调用析构函数对类里面的空间进行清理。但是malloc和free就不会调用。


🏆6.申请失败的返回值不同:

malloc申请失败的时候返回NULL指针,所以申请完以后,要进行判空。new需要捕获异常。

🎡2.new和free的实现原理:

1.对内置类型的处理:

从下面的例子也可以看出来,new可以对申请的空间进行初始化。malloc不能对申请的空间进行初始化,calloc虽然可以初始化,但是都是0,不能根据具体的实际情况进行初始化,所以也是不能初始化。

代码语言:javascript
代码运行次数:0
运行
复制
#include<iostream>
using namespace std;

int main()
{
	//申请一个int空间
	int* p1 = new int(10);

	//malloc申请空间的大小,不进行初始化
	int* p2 = (int*)malloc(sizeof(int));

	//calloc进行初始化,每个字节都初始化为0
	int* p3 = (int*)calloc(1, sizeof(int));

	//对空间进行扩容,如果为空指针,功能相当于malloc
	int* p4 = (int*)realloc(nullptr, sizeof(int));

	//申请多个int空间,后面跟着初始化列表
	int* p5 = new int[5] {1, 2, 3};

	free(p2);
	delete p1;
	//释放多个空间的时候,用delete[] 指针
	delete[] p5;
}

2.对自定义类型的处理:

在自定义这个层面,new和malloc的区别就不止有new可以进行初始化,还有new会主动调用构造函数,delete会调用析构函数。

代码语言:javascript
代码运行次数:0
运行
复制
#include<iostream>
using namespace std;

class A {
public:
	A() {
		cout << "A()" << endl;
	}
	~A() {
		cout << "~A()" << endl;
	}
private:
	int _a;
};
int main()
{
	A* p1 = new A;
	delete p1;
	cout << "aaa" << endl;

	A* p2 = (A*)malloc(sizeof(A));
	free(p2);
	cout << "aaa" << endl;
	
	return 0;
}

3.原理:

⌚️new的原理:

1.operator new函数申请空间

2.在申请的空间上调用构造函数。

⌚️delete的原理:

1.执行析构函数对对象中的资源进行清理。

2.调用operator delete对对象进行清理


new T[ ]和delete[ ]原理和上面类似。

operator new和operator delete是系统提供的全局函数,底层还是通过malloc和free进行实现的。

🎡3.为什么尽量要new和delete配套使用,malloc(calloc,realloc)和free配套使用?

因为我们如果下面这种情况下,如果是new申请的空间,用free进行释放空间,就会发生错误。

⌚️在类里面我们显式实现了析构函数的时候,用new申请多个类对象的时候,会多申请4个字节(一个int类型的大小)保存申请了多少个类。

代码语言:javascript
代码运行次数:0
运行
复制
#include<iostream>
using namespace std;

class A {
public:
	~A() {
		cout << "~A()" << endl;
	}
private:
	int _a;
};
int main()
{
	A* p1 = new A[10];

	A* p2 = (A*)malloc(sizeof(A) * 10);

	return 0;
}

这时候申请的大小是:4*10+4=44字节 但是如果没有显式实现析构函数,就不要那多出来的四个字节来保存申请了多少个类。

但是new申请的空间返回的是多申请的那四个字节的后面那10个A空间起始位置。

如果我们直接用free释放这一位置,前面多申请的那四个就没有被释放,就发生内存泄漏。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-12-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 🎡1.new,delete和malloc,free的区别:
    • ⌚️相同点:
    • ⌚️不同点:
  • 🎡2.new和free的实现原理:
    • 1.对内置类型的处理:
    • 2.对自定义类型的处理:
  • 🎡3.为什么尽量要new和delete配套使用,malloc(calloc,realloc)和free配套使用?
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档