1 内存泄漏

1.1 内存泄漏的定义

内存泄漏指的是程序在运行过程中,动态分配的内存不再被使用,却因为某些原因没有被释放,导致这部分内存一直被占用、无法被回收和再利用的现象。

在C/C++中,程序动态申请了一块堆内存,但使用完之后没有被释放,并且之后也无法再找到这块内存进行释放,这种情况称为内存泄漏。

从操作系统和进程角度而言:
程序通过 malloc/new/mmap 等向系统申请了内存;后续这块内存逻辑上已经没用了(没有指针再指向它,或业务上不会再访问);但程序没有调用 free/delete/munmap​ 把它归还给分配器或内核;
结果:进程的虚拟内存持续增长,可用内存不断减少。

1.2 典型的内存泄漏

① 忘记释放

在这里插入图片描述

在这里插入图片描述

② 指针重新指向其他地方

在这里插入图片描述

③ 异常/提前返回路径未释放

在这里插入图片描述

少量泄漏可能暂时没有明显影响,但长期运行或反复泄漏会导致进程内存占用不断增加,最终可能引起系统内存不足、性能下降甚至程序崩溃。因此动态申请的资源要保证有明确的释放责任,现代 C++ 中通常优先使用 RAII 和智能指针管理资源。

内存泄漏最终可能造成:
① 程序占用内存持续增加
② 系统可用内存越来越少
③ 程序运行变慢
④ 频繁换页,系统卡顿
⑤ 申请新内存失败
⑥ 程序崩溃
⑦ 严重时影响整个系统或其他程序

2 深拷贝与浅拷贝

① 浅拷贝是把一个对象中的成员变量,直接复制给另一个对象。对于普通成员变量,复制的是值;如果成员中存在指针,复制的是指针保存的地址,因此两个对象可能指向同一块动态内存。

② 深拷贝不仅复制成员本身,对于对象拥有的动态资源,还会重新申请一块独立内存,并把资源中的内容复制过去,因此,复制后的两个对象内容可以相同,但底层资源相互独立。

浅拷贝只复制地址,深拷贝把地址指向的数据也复制一份。 深浅拷贝问题最需要关注的是:对象内部是否管理了动态资源。

如果一个类拥有动态内存,本来需要深拷贝却使用了浅拷贝,可能会造成多个对象共享同一资源,可能出现修改一个对象影响另一个对象、悬空指针、重复释放以及未定义行为等。

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐