未调用free()却无内存泄漏?不同系统下AddressSanitizer表现差异
内存泄漏未被检测及跨环境运行异常的原因
一、AddressSanitizer未检测到内存泄漏的原因
- 运行状态与默认行为差异:在Debian 10 WSL环境中程序侥幸正常结束,但部分旧版本的AddressSanitizer默认不会主动报告进程正常退出时由操作系统回收的内存泄漏。如果需要强制检测这类泄漏,运行时需设置环境变量:
ASAN_OPTIONS=detect_leaks=1 ./wow - 崩溃中断检测流程:在Arch环境中程序因内存访问错误提前崩溃,AddressSanitizer还未执行泄漏检测逻辑就终止,自然不会输出泄漏报告。
二、跨环境运行表现不同的核心原因
你的代码存在未定义行为,根源在main函数的colSize变量:
int **colSize; // 未初始化的野指针 int** arr = make2D(rowSize, colSize);
你将一个未初始化的二级指针传入make2D,函数中执行*colSize = (int*) malloc(...)时,相当于往随机内存地址写入数据——这种行为的结果完全依赖运行环境:
- Debian 10 WSL中,这个随机地址恰好落在进程可写内存区域,程序侥幸运行完成;
- Arch 5.19中,随机地址指向不可访问的内存(如内核空间、只读区域),触发内存访问错误,即
DEADLYSIGNAL。
修复方案
1. 修复未定义行为
修改main中colSize的定义和传递方式,确保指针指向合法内存:
int main() { int *colSize; // 改为一级指针,存储列大小数组的地址 int rowSize = 2; int** arr = make2D(rowSize, &colSize); // 传递一级指针的地址给函数 print2D(rowSize, &colSize, arr); // 释放内存 for(int i=0; i<rowSize; i++){ free(arr[i]); } free(arr); free(colSize); return 0; }
2. 释放内存
添加上述代码中的内存释放逻辑,既避免内存泄漏,也能让AddressSanitizer准确检测泄漏情况。
内容的提问来源于stack exchange,提问作者altair00
相关产品推荐
相关产品推荐

