【C++】new/delete 还是 malloc/free?C++内存管理的“世纪抉择

目录

一,计算机的内存的存储

1,内存划分

2,类型的判断

3,C语言中的动态内存管理

二,C++当中的内存管理方式

1,new和delete的使用

2,new和delete的底层实现原理

3,定位new表达式

[三,总结 :malloc/free和new/delete之间的区别](#三,总结 :malloc/free和new/delete之间的区别)


一,计算机的内存的存储

1,内存划分

首先看下面这张图,这张图片展示了C/C++程序内存区域的各个部分:

栈的内存由高到低进行开辟,而堆的内存由低到高进行开辟。

内存空间在不同位下的效果:

2,类型的判断

globalvar:全局变量在静态区

staticGlobalvar:静态全局变量也在静态区

这两个的核心区别就是:全局变量可以在这个工程下的其他文件中进行使用,但是静态修饰的变量只能在当前文件下进行使用。

staticvar:静态的局部变量也在静态区

localvar/num1/char2:局部变量和数组都在栈中

*char2:表示首元素,依旧在栈中

pchar3:常量字符串指针,在栈中

*pchar3:表示常量字符串,在代码段当中

ptr1:表示开辟空间的指针,在栈中

*ptr1:表示开辟的空间,在堆中

3,C语言中的动态内存管理

在学习C++中的内存管理函数之前,需要先复习一下C语言当中的内存管理函数。

C语言当中内存管理:malloc/calloc/realloc/free

二,C++当中的内存管理方式

1,new和delete的使用

虽然C语言当中动态开辟内存的方式在C++当中依然可以进行使用,但是C++开创了自己内存管理的方式,即:通过new和delete操作符进行动态内存管理

内置类型的动态内存开辟:

自定义类型的内存开辟:

总结:在申请空间时,new会调用构造函数 ,delete会调用析构函数,但是malloc和free不会

除此之外,malloc会进行判空防止开辟失败,new开辟空间失败,会抛出异常。

展示:

32位下:

由此可见32位下在堆上申请1.8G左右的内存,而栈上一般申请8MB左右的内存

2,new和delete的底层实现原理

要想了解new和delete的底层原理,就要先知道operator new和operator delete函数

首先new和delete是用户开辟空间和释放空间的操作符,operator new和operator delete是系统提供的底层函数,new在底层调用operator new,delete在底层调用operator delete全局函数来释放空间。

operator new 的底层还是malloc,如果申请成功就返回,如果申请失败就抛出异常

operator delete的底层还是free来释放空间

自定义类型:

new的原理:

1,调用operator new函数申请空间

2,在申请的空间上使用构造函数,进行初始化

delete的原理:

1,调用析构函数,清理对象当中开辟的资源和空间。

2,调用operator delete函数释放对象中的空间。

注意:自定义类型new/free,malloc/delete不能进行混用,可能会出现内存泄漏等问题。

总结:不要错配使用,new/delete搭配,malloc/calloc/realloc/free搭配

3,定位new表达式

在某些时候我们将new的两个组成部分进行拆分使用,就要用到new表达式

new表达式:在已经分配的内存空间中调用构造函数并初始化一个对象 。

使用形式:new(对象名)对象类型(向构造函数传入的值)

展示:

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 = new A(1);
	delete p1;
	//进行拆分--调用operator new相当于malloc
	A* p2 = (A*)operator new(sizeof(A));
	//定位new表达式--在已经分配内存的空间中调用构造函数并初始化为2
	new(p2)A(2);
	//可以直接通过指针调用析构函数
	p2->~A();
	operator delete(p2);
	return 0;
}

定位new表达式的使用场景比较少,一般是配合内存池进行使用,了解一下即可。

三,总结 :malloc/free和new/delete之间的区别

共同点:malloc/free和new/delete的共同点就是都需要从堆申请空间,并且需要手动释放空间。

不同点

对比项 malloc / free new / delete
语言 C/C++ C++
类型 函数 运算符
调用构造/析构 ❌ 不调用 ✅ 调用
返回值类型 void*(需强转) 类型安全不需要进行强转
失败处理 返回 NULL(手动判空) 抛异常(自动抛出)
内存大小 手动计算 自动计算
数组支持 无特殊支持 new[] / delete[](直接通过个数开辟)
可重载
分配失败可扩容 可通过 realloc 调整 无直接对应(需自己实现)

malloc/free是标准库函数,标准库函数不能够进行重载,但是new/delete是操作符,操作符可以进行重载。