c++如何用AddressSanitizer检测内存错误

来源:站长平台作者:松松建站头衔:草根站长
导读:本期聚焦于小伙伴创作的《c++如何用AddressSanitizer检测内存错误》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《c++如何用AddressSanitizer检测内存错误》有用,将其分享出去将是对创作者最好的鼓励。

AddressSanitizer是gcc和clang编译器内置的内存错误检测工具,能够在程序运行时发现堆、栈、全局变量区域的内存越界、使用已释放内存、内存泄漏等常见问题,相比传统调试工具定位效率更高。

c++如何用AddressSanitizer检测内存错误

asan的基本使用原理

asan会在编译阶段对代码进行插桩,在每次内存操作前后添加检查逻辑,同时会在内存区域周围设置红区,当程序访问到红区或者已释放的内存区域时,就会触发错误报告,输出详细的错误信息和调用栈。

编译阶段开启asan

使用gcc或者clang编译c++程序时,只需要添加对应的编译参数即可开启asan,不同编译器的参数略有区别。

gcc编译器配置

gcc从4.8版本开始支持asan,编译时添加-fsanitize=address参数,同时建议添加-g参数保留调试信息,方便定位错误位置。

// 编译单个cpp文件
g++ -fsanitize=address -g test.cpp -o test

// 如果是多文件项目,每个编译单元都需要添加该参数
g++ -fsanitize=address -g main.cpp func.cpp -o app

clang编译器配置

clang的asan开启方式和gcc类似,同样使用-fsanitize=address参数,部分版本可能需要额外添加-fno-omit-frame-pointer参数保证调用栈信息完整。

clang++ -fsanitize=address -g -fno-omit-frame-pointer test.cpp -o test

常见内存错误检测示例

堆内存越界访问

堆内存越界是c++中最常见的内存错误之一,下面是一段触发堆越界的示例代码。

#include <iostream>
#include <cstdlib>

int main() {
    // 分配10个int大小的内存
    int* arr = new int[10];
    // 越界访问第11个元素,触发asan错误
    arr[10] = 100;
    delete[] arr;
    return 0;
}

编译运行后,asan会输出错误类型、越界的内存地址、访问大小以及完整的调用栈,能直接定位到越界访问的代码行。

使用已释放内存

释放内存后继续访问该内存区域也是常见错误,示例代码如下。

#include <iostream>

int main() {
    int* p = new int(10);
    delete p;
    // 使用已释放的内存,触发asan错误
    *p = 20;
    return 0;
}

asan会检测到该操作属于use-after-free错误,同时会显示内存释放的位置和当前访问的位置。

栈内存越界

栈上的局部变量越界同样可以被asan检测到,示例代码如下。

#include <iostream>

int main() {
    int stack_arr[5];
    // 栈内存越界访问
    stack_arr[5] = 10;
    return 0;
}

asan的常用配置选项

可以通过环境变量对asan的行为进行配置,常用的配置项如下:

  • ASAN_OPTIONS=detect_leaks=1:开启内存泄漏检测,默认情况下asan会检测内存泄漏,部分场景可能需要手动开启
  • ASAN_OPTIONS=abort_on_error=1:检测到错误后立即终止程序,方便自动化测试场景使用
  • ASAN_OPTIONS=print_stacktrace=1:强制输出调用栈信息,默认已经开启

设置环境变量的方式如下,在运行程序前执行:

export ASAN_OPTIONS=detect_leaks=1:abort_on_error=1
./test

注意事项

使用asan时需要注意以下几点:

  • 开启asan后程序运行速度会下降2-3倍,内存占用会增加2-3倍,不适合生产环境使用,仅用于调试阶段
  • 如果项目使用了自定义的malloc/new实现,可能会和asan的内存管理逻辑冲突,需要暂时关闭自定义实现
  • 部分老版本的编译器对asan的支持不完善,建议尽量使用较新版本的gcc或者clang
asan只能检测运行时的内存错误,无法检测编译期的语法错误,也不能覆盖所有场景的内存问题,需要结合其他调试工具共同使用。

AddressSanitizerc++内存错误检测asan使用方法修改时间:2026-07-10 07:54:29

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。