内存问题 2025-09-28

写程序的时候都会遇到哪些内存问题

内存问题类型 主要含义 潜在影响与常见场景
内存泄漏 (Memory Leak) 分配的内存未能释放,不再使用的内存无法回收 。 应用程序内存逐渐耗尽,运行变慢,甚至异常终止 。长期运行的系统(如服务器、后台服务)影响更大。
内存溢出 (Out of Memory) 程序申请内存时,系统没有足够的空间满足其请求 。 程序运行中断或崩溃。常见于处理大量数据、内存设置过小或内存泄漏积累后 。
内存越界 (Out-of-Bounds Access) 访问了分配时规定的内存范围之外的空间(如数组越界)。 数据损坏:可能破坏其他变量或关键数据;程序崩溃:访问非法地址时触发;安全漏洞:可能被利用执行恶意代码 。
缓冲区溢出 (Buffer Overflow) 向缓冲区(如数组)写入超过其容量的数据,覆盖了相邻内存 。 同内存越界类似,但常强调因写入过多数据导致溢出,是安全攻击的常见目标 。
悬空指针/野指针 (Dangling Pointer/Wild Pointer) 指针指向的内存已被释放或未初始化 。 访问它们会导致未定义行为,如读取到垃圾数据或程序崩溃 。
访问未初始化内存 (Accessing Uninitialized Memory) 读取了未赋初值的内存内容,值不确定 。 程序行为不可预测,结果可能错误 。
双重释放 (Double Free) 对同一块动态内存释放了两次 。 可能破坏内存管理器的数据结构,导致程序崩溃或潜在的安全问题 。
内存碎片 (Memory Fragmentation) 虽有足够的总空闲内存,但缺乏大的连续块来满足分配请求 。 可能导致内存分配失败(即使总内存足够),降低内存使用效率 。
  • 内存泄漏 (Memory Leak):指的是程序未能释放不再使用的内存。就像水池有个小洞在不停漏水,可用内存逐渐减少。积累到一定程度就可能引发内存溢出。
    • 常发性内存泄漏:发生内存泄漏的代码会被多次执行到,每次执行都导致一块内存泄漏 。
    • 偶发性内存泄漏:发生内存泄漏的代码只有在某些特定环境或操作过程下才会发生 。
    • 一次性内存泄漏:发生内存泄漏的代码只会被执行一次,或者由于算法缺陷,导致总有且仅有一块内存发生泄漏 。
    • 隐式内存泄漏:程序在运行过程中不停的分配内存,直到结束时才释放。对于需长期运行的程序(如服务器),这可能导致内存耗尽 。

我对于内存问题在写代码的应对方式

第一个肯定是良好的编程习惯

遵循RAII原则()、使用智能指针(想要做的就是对资源的及时回收防止内存泄漏)
注意不要栈溢出(比如说递归终止条件、有栈协程分配空间的时候)、容器或数组的越界、程序向系统索要内存问题。

编译阶段

(c/c++)
ASan: 内存错误
TSan: 线程竞争
UBSan: 未定义行为
LSan: 内存泄漏

Sanitizer工具 检测的问题
AddressSanitizer (ASan) 内存越界、use-after-free
UndefinedBehaviorSanitizer (UBSan) 整数溢出、除零、空指针
ThreadSanitizer (TSan) 多线程数据竞争
LeakSanitizer (LSan) 内存泄漏

使用问题

(仅在测试阶段使用)
TSan一般要单独使用(因为与UBSan不兼容)
LSan以及集成到ASan中了

g++ -o my_program my_program.cpp -g -fsanitize=<sanitizer_name>
LSan
g++ -o my_program my_program.cpp -g -fsanitize=leak
ASan
g++ -o my_program my_program.cpp -g -fsanitize=address
UndefinedBehaviorSanitizer (UBSan)
g++ -o my_program my_program.cpp -g -fsanitize=undefined
TSan
g++ -o my_program my_program.cpp -g -fsanitize=thread

也可以集成使用,通常是将ASan与UBSan集成

g++ -o my_program my_program.cpp -g -fsanitize=address,undefined
//
g++ -O1 -g -fno-omit-frame-pointer -fsanitize=address,undefined -o my_program my_program.cpp
# 注意:LeakSanitizer (leak) 不需要显式写出,因为它已包含在 address 中。

放到cmake中

cmake_minimum_required(VERSION 3.10)
project(MyProject)

# 创建可执行文件
add_executable(my_program my_program.cpp)

# 为特定目标设置编译和链接选项
target_compile_options(my_program PRIVATE 
    -O1 
    -g 
    -fno-omit-frame-pointer 
    -fsanitize=address,undefined
)

# Sanitizer 通常也需要链接相应的运行时库
target_link_libraries(my_program PRIVATE 
    -fsanitize=address,undefined
)

Valgrind

(c/c++ linux)

wait....

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容