当前位置: 首页 > ds >正文

C/C++中的内存管理

C/C++ 中程序使用的内存区域

C中的动态内存管理 

malloc

申请 size 大小的空间

int* pi = (int*)malloc(sizeof(int) * 10);

calloc

申请 num 个 size 大小的空间,
并初始化为 0 值
int* pi = (int*)calloc(10, sizeof(int));

realloc

将 ptr 指向的空间,扩容至 size 大小
int* new_pi = (int*)realloc(pi, sizeof(int)*100);

free

释放掉由 malloc、calloc、
realloc 申请的空间
free(new_pi);

小结

C中的动态内存管理方式,不能很好地支持自定义类型,所以 C++ 中有了 new 和 delete

A* a = (A*)malloc(sizeof(A));	// 为 A 类型申请空间,但不能初始化

C++中的动态内存管理

new & delete

    int* pi = new int;	// 申请 1 个 int 类型的空间int* pi1 = new int(0);	// 初始化为 0int* pi2 = new int[10];	// 申请 10 个 int 类型的空间A* pa = new A;	// 申请 1 个 A 类型的空间,并调用默认构造初始化delete pi;delete pi1;delete[] pi2;delete pa;    // 调用 A 类的析构函数,并释放空间

使用 new 动态申请的内存,必须使用 delete 释放

与 C 中对动态内存管理方式的区别:

对于自定义类型,new 会开空间 + 调用构造函数初始化,delete 会调用析构函数 + 释放空间。

但是对内置类型,处理基本一样,开空间但不会初始化。

另外,new 在申请空间失败后会抛出异常,需用 try catch 捕获;malloc 申请失败后,会返回 NULL

new[ ] & delete[ ]

	A* pa = new A[10];delete[] pa;

new A[n] 和 delete[ ] pa 是对多个对象空间的申请和释放操作,其中,分别调用了 operator new[ ] 与 operator delete[ ] 函数;过程与单个对象空间的申请与释放,基本没有区别。

但是为多个对象开辟和释放空间时,一般 new 会额外开辟空间存取开辟的对象个数(不同编译器的实现方式可能不同),以便 delete 时,编译器知道该释放掉多大空间。

operator new

针对自定义类型,使用 new 创建对象,实际上做了两步操作

(1)调用了底层的 operator new 这个全局函数申请空间

(2)调用该自定义类型的构造函数

如下图(vs中 new 对象,调试时的汇编指令),在整个 new 对象的过程中, call 了两个函数:operator new 和 A 类的默认构造:

借鉴一下C友的源码:

void* __CRTDECL operator new(size_t const size)
{for (;;){if (void* const block = malloc(size))    // 调用了 malloc{return block;}if (_callnewh(size) == 0){if (size == SIZE_MAX){__scrt_throw_std_bad_array_new_length();}else{__scrt_throw_std_bad_alloc();}}// The new handler was successful; try to allocate again...}
}

发现 operator new 函数中,实际调用了 malloc 来申请内存

operator delete

同理,针对自定义类型,C++ 中的 delete 也是分两步走:

(1)调用该类型的析构函数

(2)调用 operator delete 释放申请的空间

void __CRTDECL operator delete(void* const block) noexcept
{#ifdef _DEBUG_free_dbg(block, _UNKNOWN_BLOCK);#elsefree(block);#endif
}

operator delete 的源码中,仍然是调用了 free 来释放内存。

operator new[ ] & operator delete[ ]

同单个对象的空间申请与释放步骤一样,多个对象 new A[ ] 和 delete[ ] p 时:

new A[ ] :调用多次operator new[ ] + 构造函数

delete [ ] p :调用多次析构函数 + operator delete[ ]

小结

new 和 delete、malloc 和 free 匹配使用,否则行为将未定义。

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

区别:

1、malloc 和 free 时函数,new 和 delete 是操作符;

2、malloc 申请的空间不会初始化,而 new 可以初始化;

3、malloc 申请空间时,需要手动计算大小并传参;而 new 只需要在后面跟上类型以及对象个数;

4、malloc 的返回值为 void* ,需要强制转换指针;而 new 因为后跟类型的原因,不需要转换指针类型;

5、malloc 申请失败返回 NULL,对 malloc 使用必须加判空语句;而 new 需要捕获异常;

6、针对自定义类型,malloc/free 只能开辟空间,不会调用构造函数和析构函数;而 new/delete 会在申请空间时调用构造函数完成对象的初始化,delete 会在释放空间之前调用析构函数完成空间中的资源清理。

思考:new 和 delete 目的就是在面向对象编程中,支持自定义类型对象的空间申请、初始化以及资源释放。

http://www.xdnf.cn/news/16257.html

相关文章:

  • [Linux入门] Linux 文件系统与日志分析入门指南
  • arm64架构开发板上调用奥比中光深度摄像头用于视觉测距
  • 判断矩形能否放入多边形内——cad c# 二次开发实现
  • 初识opencv02——图像预处理1
  • 软硬件协同仿真和验证的标准接口协议SCE-MI简介
  • Spring语法2
  • HTML5 网页游戏设计开发——1、HTML基础
  • PowerShell自动化核对AD与HR系统账户信息实战指南
  • 趣玩-Ollama-Llm-Chatrbot
  • Flask框架全面详解
  • DeepSeek Janus Pro本地部署与调用
  • 技术速递|使用 Semantic Kernel 与 A2A 协议构建多智能体解决方案
  • 三大论坛联动,2025合成生物学盛会助力生物制造高质量发展
  • AI安全“面壁计划”:我们如何对抗算法时代的“智子”封锁?
  • 直播软件搭建与原生直播系统开发全解析
  • 架构师--缓存场景
  • 【Linux-云原生-笔记】Haproxy相关
  • SQL难点突破之复杂业务逻辑的SQL查询实战
  • Hexo - 免费搭建个人博客02 - 创建个人博客
  • 从8h到40min的极致并行优化:Spark小数据集UDTF处理的深度实践与原理剖析
  • C++day1
  • 想曰加密工具好用吗?本地安全、支持多算法的加密方案详解
  • 基于Dapr Sidecar的微服务通信框架设计与性能优化实践
  • 设计模式 八:原型模式 (Prototype Pattern)
  • .NET-键控服务依赖注入
  • LeetCode|Day23|326. 3 的幂|Python刷题笔记
  • 认识Transformer架构
  • 第十讲:stack、queue、priority_queue以及deque
  • 【力扣】第15题:三数之和
  • C# 继承 虚方法