C/C++内存管理

先上一张图,简洁明了:

C语言在动态内存管理方面,有malloc/calloc来动态申请内存,realloc来进行对所申请内存大小的调整,free进行动态内存的释放。但C++中由于面向对象思想的提出,有构造函数来初始化对象,析构函数来进行对象中资源的清理,以及C++异常机制的提出,使得C语言的动态内存管理的相关机制已经不能满足C++的应用场景了,因此C++给出了new/delete操作符来进行C++的动态内存管理 ,使得C++的内存管理更加灵活。

new/delete

具体使用:

cpp 复制代码
#include<iostream>
#include <string>
class A
{
public:
	A(int num = 0, std::string message = "hello")
		:_num(num),
		_message(message)
	{}
private:
	int _num;
	std::string _message;
};
int main()
{
	int* p1 = new int;
	char* pch = new char;
	A* pa = new A(10, "hello world!");
	int* array = new int[10];

	delete p1;
	delete pch;
	delete pa;
	delete[] array;
	return 0;
}

注意事项:申请和释放单个元素空间时,使用new/delete,申请多个元素的连续空间时,使用new[ ]和delete[ ]。

operator new/operator delete

(1)new和delete是用户进行动态内存申请和释放的操作符,operator new 和operator delete是系统提供的全局函数,new在底层调用operator new全局函数来申请空间,delete在底层通过operator delete全局 函数来释放空间。

(2)operator new 实际是通过malloc来申请空间,如果malloc申请空间成功就直接返回,否则执行用户提供的空间不足应对措施,如果用户提供该措施就继续申请,否则就抛异常。operator delete 最终是通过free来释放空间的。

new/delete实现原理

内置类型

如果是内置类型,new/delete和malloc/free基本类似,不同的是malloc/free进行单个元素空间的申请,new[ ]/delete[ ]进行连续多个元素空间的申请。并且malloc失败返回NULL,new失败抛异常。

自定义类型

(1)如果是自定义类型,malloc/free只会进行对应大小的空间申请,并不会对资源进行初始化,而new会在调用operator new申请对应的空间后,自动调用该类的构造函数来进行资源的初始化,delete则会在调用operator delete释放资源之前先调用对应类的析构函数来进行资源的清理。

(2)new T[N]先调用operator new[ ]申请N个T的空间,再调用N次T的构造函数来进行资源的初始化,delete[N]则是会先调用N次对应类的析构函数来进行资源的清理,再调用operator delete[ ]释放申请的空间。

定位new

用于对申请的动态内存进行资源初始化。场景:只通过malloc进行了对应空间的申请,却没有调用对应的构造函数来进行资源的初始化,此时就可以用定位new来完成对应资源的初始化。

使用格式: new (place_address) type或者new (place_address) type(initializer-list) place_address必须是一个指针,initializer-list是类型的初始化列表。

具体使用:

cpp 复制代码
#include<iostream>
#include <string>
class A
{
public:
private:
	int _num;
	std::string _message;
};
int main()
{
	A* pa = (A*)malloc(sizeof(A));
	new(pa)A;
	return 0;
}

new/delete与malloc/free的不同

(1)new/delete是操作符,而malloc/free是函数。

(2)malloc在申请空间时,需要计算所要申请空间的字节数,new只需要在其后添加类型,申请多个时,只需要在new[ ]的[ ]中填写要申请的个数即可。

(3)malloc申请空间失败时返回NULL,new申请空间失败时抛异常。

(4)malloc/free只是申请和释放了空间,而new/delete则会在申请对应空间后调用对应的构造函数来进行资源的初始化,也会在释放对应空间前先调用对应的析构函数来进行资源的清理。

(5)malloc在申请成功的情况下的返回值是void*,使用时需要用户进行对应类型的强制类型转换,new则不需要,返回的是对应类型的指针。

相关推荐
水力魔方10 分钟前
武理排水管网模拟分析系统应用专题5:模型克隆与并行计算
数据库·c++·算法·swmm
cike_y12 分钟前
Spring-Bean的作用域&Bean的自动装配
java·开发语言·数据库·spring
十八度的天空1 小时前
第01节 Python的基础语法
开发语言·python
OliverH-yishuihan1 小时前
在win10上借助WSL用VS2019开发跨平台项目实例
linux·c++·windows
yue0081 小时前
C# 字符串倒序
开发语言·c#
强子感冒了1 小时前
Java学习笔记:String、StringBuilder与StringBuffer
java·开发语言·笔记·学习
低保和光头哪个先来1 小时前
场景6:对浏览器内核的理解
开发语言·前端·javascript·vue.js·前端框架
小北方城市网1 小时前
Python + 前后端全栈进阶课程(共 10 节|完整版递进式|从技术深化→项目落地→就业进阶,无缝衔接基础课)
大数据·开发语言·网络·python·数据库架构
程序员JerrySUN1 小时前
OP-TEE + YOLOv8:从“加密权重”到“内存中解密并推理”的完整实战记录
android·java·开发语言·redis·yolo·架构
阿里嘎多学长2 小时前
2025-12-30 GitHub 热点项目精选
开发语言·程序员·github·代码托管