munmap_chunk(): invalid pointer 是 glibc 堆检查机制触发的错误,表明程序对非法地址(如栈内存、重复释放地址、偏移指针或非 malloc/new 分配的内存)执行了 free() 或 delete[]。

这是典型的堆内存管理错误,不是数组本身的问题,而是 free() 或 delete 作用在了非法地址上 —— 比如未用 malloc/new 分配的内存、重复释放、或指针已被篡改。
为什么 munmap_chunk(): invalid pointer 会出现在 C++ 数组操作中
这个错误来自 glibc 的堆检查机制,说明程序试图用 free()(或 delete)释放一个它不认识的地址。C++ 中常见诱因包括:
- 对栈上数组(如
int arr[10];)调用delete[] arr; - 用
new分配但用delete[]释放(或反过来) - 指针偏移后直接释放(如
int* p = new int[5]; p++; delete[] p;) - 释放后继续使用该指针,再二次释放
- 跨 DLL/so 边界传递并释放内存(尤其 Windows 下 CRT 不一致时)
如何快速定位出错的那行 delete 或 free
别靠猜。启用地址 sanitizer 是最有效的方式:
g++ -fsanitize=address -g your_file.cpp -o your_prog
运行后会精确打印出非法释放发生的位置、调用栈,以及该指针此前分配/释放的历史。注意:-fsanitize=address 会显著拖慢运行速度,但值得——它能暴露绝大多数堆误用。
若无法编译加 ASan(如生产环境复现),可临时替换全局 operator new/delete,或用 valgrind --tool=memcheck ./your_prog(Linux 下更轻量,但对 munmap_chunk 类错误不如 ASan 直观)。
new[] / delete[] 和 malloc / free 混用的坑
C++ 标准严禁混用:用 new[] 分配的内存必须用 delete[] 释放;用 malloc 分配的必须用 free 释放。混用会导致:
-
new[]+free():绕过析构函数,且 glibc 可能因元数据不匹配报invalid pointer -
malloc+delete[]:触发未定义行为,常见崩溃点 - 即使类型是 POD(如
int),也不能侥幸混用 —— 内存管理器依赖分配时埋入的头部信息
示例错误:
int* p = new int[100]; free(p); // ❌ 危险!
正确写法:
int* p = new int[100]; delete[] p; // ✅
或:
int* p = (int*)malloc(100 * sizeof(int)); free(p); // ✅
容易被忽略的边界情况:容器内部指针、std::vector::data() 和 realloc
很多开发者以为“只要没手写 new 就安全”,但以下情况仍可能触发该错误:
- 从
std::vector拿到data()后,对它调用delete[](data()返回的是托管内存,不能手动释放) - 用
realloc()调整malloc来的内存后,忘记更新原始指针,导致后续free()传入旧地址(realloc可能移动内存) - C 风格 API 返回的缓冲区(如某些图像库的
get_pixels())注明“由调用方管理”,但实际文档写错,或该指针根本不是堆分配的
关键判断原则:只释放你明确用 malloc/calloc/realloc 或 new/new[] 获得的指针;所有 STL 容器、智能指针、RAII 对象内部的内存,交由它们自己管理。
真正麻烦的往往不是语法错误,而是指针在多层函数间传递后被悄悄修改,或者在异常路径里漏掉释放 —— 这类问题必须结合 ASan 日志和调用上下文逐帧确认,不能只看报错那一行。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











