Emscripten中AddressSanitizer未检测到内存泄漏的原因咨询
为什么未使用的new分配内存无法被Emscripten的AddressSanitizer检测到?
没错,这就是编译器优化导致的结果。
当你分配了testi但完全没有使用这个指针时,编译器会判定这个内存分配操作是无意义的冗余代码,在编译过程中直接把它移除了——既然代码都没执行,自然不会产生内存泄漏,AddressSanitizer(LSAN)也就检测不到。
具体差异分析
- 第一个测试版本中,你读取了
testi[0],这意味着指针testi被实际使用,编译器无法安全删除内存分配操作,new int[10]会被正常执行,因此泄漏能被LSAN捕获。 - 修改后的版本里,
testi指针没有被任何代码引用,编译器的**死代码消除(Dead Code Elimination)**优化会直接去掉new int[100]整个操作,函数执行时根本不会分配内存,自然不存在泄漏。
验证与解决方法
- 关闭优化验证:编译时添加
-O0参数禁用所有优化,此时即使testi未被使用,new操作也会被保留,LSAN就能检测到泄漏。 - 保留优化的前提下强制保留分配:给指针添加
volatile修饰符,告诉编译器该指针可能被外部使用,不能随意优化:
int leak() { volatile auto testi = new int[100]; // 泄漏会被检测到 return 2; }
内容的提问来源于stack exchange,提问作者Zamah
相关产品推荐
相关产品推荐

