mismatched free()/delete/delete[] 是明确的内存管理错误,表明分配与释放函数不匹配,如 new[] 与 delete 混用,需立即修正为 delete[] 或对应 free()。

看到 Mismatched free() / delete / delete[] 就该停下手头工作
这不是警告,是明确的内存管理错误。Valgrind 报出 Mismatched free() 说明你用错了释放函数——比如用 free() 释放了 new[] 分配的内存,或用 delete 释放了 malloc() 来的指针。这种错在运行时可能不崩溃,但行为未定义,早晚出问题。
怎么快速定位 mismatch 的源头
看 Valgrind 报告里两段关键堆栈:
- “
Address 0x... is 0 bytes inside a block of size 40 alloc'd” —— 这行告诉你内存是怎么分配的:operator new[]、malloc还是new - “
Invalid free() / delete / delete[]” —— 这行告诉你实际用了哪个释放函数
只要这两者不匹配,就是 bug。常见组合错误有:
-
new[]+delete(缺中括号)→ 改成delete[] -
malloc()+delete或delete[]→ 改成free() -
new+delete[]→ 改成delete -
calloc()/realloc()+delete→ 只能配free()
C++ 里 new/delete 和 malloc/free 混用的坑
尤其 Qt 或 C++ 项目里容易踩这个坑:比如在构造函数里用 new char[1024],析构里却写 free(p)。Valgrind 会直接报:
1: operator new[](unsigned long) in ...<br>2: MainWindow::MainWindow(QWidget*) in mainwindow.cpp:13<br>...<br>1: operator delete(void*) in ...<br>2: MainWindow::MainWindow(QWidget*) in mainwindow.cpp:14
注意第 1 行的 operator new[] 和第 1 行释放处的 operator delete(void*) —— 后者是 delete(单对象),不是 delete[]。改法就一行:delete[] p; 替掉 delete p; 或 free(p);。
编译和运行时的小动作能省一半排查时间
别等上线才跑 Valgrind。日常开发建议:
- 编译加
-g -O0,确保报告能准确定位到.cpp行号 - 命令里加
--leak-check=full --show-leak-kinds=all --track-origins=yes,虽然慢,但对 mismatch 类错误能反向追到分配点 - 如果项目混用 C 风格和 C++ 风格内存管理,考虑统一:Qt 项目优先用
new/delete,纯 C 模块坚持malloc/free,中间加个 wrapper 层隔离
最麻烦的不是改错,而是有人把 new char[N] 写成 new char(N)(少了一对方括号),结果分配的是单字节对象,再 delete[] 就又 mismatch。这种拼写错误 Valgrind 也能抓到,但得靠人盯住分配那行的语法。











