会,但仅在启用--leak-check=full等参数并配合-g、-o0、-fno-omit-frame-pointer等编译选项时才能显式检测new/delete不匹配,否则常以invalid free或内存泄漏等形式间接暴露。

Memcheck 会报 Mismatched use of new / delete 吗
会,但只在特定条件下触发。Memcheck 默认能识别 new 和 delete、new[] 和 delete[] 的不匹配,但不会报告 new + delete[] 或 new[] + delete 这类错误——除非你显式启用 --tool=memcheck --freelist-vol=1000000 --leak-check=full 并配合 -fno-omit-frame-pointer 编译。实际中更常见的是它把这类不匹配当作“无效释放”或“非法内存访问”间接暴露出来。
编译时必须加的几个关键选项
不加这些,Memcheck 很可能漏掉不匹配问题,甚至完全不报错:
-
-g:保留调试符号,否则报错不带行号,定位不到具体哪行new/delete -
-O0(禁用优化):避免编译器内联或消除分配/释放逻辑,导致 Memcheck 捕获不到调用点 -
-fno-omit-frame-pointer:确保栈帧信息完整,对new[]/delete[]匹配判断至关重要 -
-fno-inline(C++ 项目建议加上):防止函数内联后new和delete调用被合并或隐藏
运行时怎么让 Memcheck 显式指出不匹配
单纯跑 valgrind ./a.out 可能只报 Invalid write 或 Invalid free,而不会直接说“你用了 new[] 却调 delete”。要让它明确提示,得加参数:
-
--tool=memcheck(默认可省略) -
--leak-check=full:开启完整泄漏检查,会追溯每块内存的分配/释放路径 -
--show-leak-kinds=all:显示definitely lost、possibly lost等全部类型 -
--track-origins=yes:对未初始化值或越界访问追根溯源,间接帮你发现因不匹配引发的后续异常
典型命令:valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes ./my_program
看到哪些错误信息说明大概率是 new/delete 不匹配
Memcheck 不会直说“new[] 对应了 delete”,但以下几类输出高度提示该问题:
-
Invalid free() / delete / delete[]:尤其当错误行指向delete语句,但分配处显示operator new[](unsigned long) -
Address 0x... is 0 bytes after a block of size N alloc'd:释放后还试图访问,常因delete销毁了数组对象但后续仍按数组用 -
Conditional jump or move depends on uninitialised value(s):new[]分配的原始内存未初始化,又被delete错误释放后残留指针访问 - 泄漏报告里出现
at 0x...: operator new[](unsigned long) (in /usr/lib/...),但没对应operator delete[](void*)调用
真正难缠的是那种“程序没崩、也没明显报错,但泄漏数随循环递增”的情况——这时翻泄漏报告里 new[] 的调用栈,再 grep 代码里对应位置是否用了 delete 而非 delete[],基本就锁定了。
别指望 Memcheck 自动修代码;它只负责暴露 mismatch 的后果。最可靠的防线,还是写 new[] 的瞬间就敲出 delete[],中间插任何逻辑都先用智能指针兜底。











