try/catch仅能捕获显式throw或标准库明确声明抛出的C++异常,无法捕获段错误、访问违规等操作系统信号;应优先采用防御性编程、错误码和调试工具而非依赖catch(...)兜底。

直接用 try 和 catch 就能捕获 C++ 异常,但多数崩溃不是由 throw 触发的——比如空指针解引用、数组越界、除零这些,C++ 标准不保证抛出异常,try/catch 压根捕不到。
哪些异常能被 try/catch 捕获
只能捕获显式 throw 出来的异常,或标准库中明确声明会抛异常的函数(如 std::vector::at() 越界时抛 std::out_of_range)。
-
std::string构造失败可能抛std::bad_alloc -
dynamic_cast对指针返回nullptr,但对引用失败时会抛std::bad_cast -
std::stoi解析失败抛std::invalid_argument或std::out_of_range - 自己写的函数里用
throw std::runtime_error("xxx"),当然也能被捕获
为什么 try/catch 捕不到段错误、访问违规
这类是操作系统信号(Unix 的 SIGSEGV,Windows 的 ACCESS_VIOLATION),属于底层硬件/运行时异常,不在 C++ 异常机制范围内。C++ 的 try/catch 是语言级控制流,和信号处理完全无关。
- 想拦截段错误,得用
signal()(POSIX)或SetUnhandledExceptionFilter()(Windows),但这属于平台相关且高危操作 - 启用编译器选项(如 GCC 的
-fsanitize=address)可在调试期检测越界,但不是运行时捕获 -
std::set_terminate()只在未捕获异常终止前调用,对信号无效
catch(...) 能兜住一切?
不能。它只捕获 C++ 异常对象,不捕获信号、不捕获 C 风格 longjmp、不捕获 Windows SEH 异常(除非编译器开启特定兼容模式,如 MSVC 的 /EHa)。
立即学习“C++免费学习笔记(深入)”;
-
catch(...)在 MSVC 下配合/EHa可捕获 SEH,但会破坏栈展开语义,导致RAII失效(析构函数可能不执行) - Clang/GCC 默认不支持 SEH,
catch(...)仅对标准 C++ 异常有效 - 即使能捕获,也不建议用
catch(...)替代错误检查——它掩盖了问题类型,不利于定位
真正健壮的错误处理怎么做
别依赖 try/catch 拦截所有错误。优先用防御性编程 + 明确错误码 + 工具链辅助。
- 用
std::vector::at()替代operator[],主动触发可捕获异常 - 对指针解引用前判空,对整数除法前检查除数是否为零
- 启用
-D_GLIBCXX_DEBUG(libstdc++)或_ITERATOR_DEBUG_LEVEL=2(MSVC)获取容器越界诊断 - 生产环境用
core dump+gdb或WinDbg分析崩溃点,比试图“捕获”更可靠
异常机制设计初衷是处理“异常但可预期”的错误(如文件不存在、网络超时),不是替代空指针检查或边界校验。混淆这两者,代码会越来越难维护。











