C++异常捕获后程序coredump、Matrix自定义异常编译报错排查
问题原因
程序触发coredump、异常未被捕获是三类错误共同导致的:
IllegalOperation异常类构造函数语法错误,导致编译失败- 运算符重载中抛出的异常类型与catch块声明的捕获类型不匹配,未被捕获的异常直接触发
std::terminate终止程序 - 嵌套异常类的模板实例化类型不统一,部分场景抛出的异常无法被现有catch块匹配
1. 修复异常类的语法错误
你写的异常类构造函数遗漏了成员初始化列表的冒号,编译器会把初始化列表内容识别成函数声明,直接报编译错误。
原错误代码:
IllegalOperation(const char *msg) _msg(msg){};
修正后的异常类完整定义(注意要提前包含依赖头文件):
// matrix.h开头需要包含这两个头文件 #include <exception> #include <string> // Error class class IllegalOperation : public std::exception { public: IllegalOperation(const char *msg) : _msg(msg) {}; // 初始化列表前补冒号 const char *what() const noexcept override { return _msg.c_str(); }; private: std::string _msg; };
注:C++11及以后版本推荐用noexcept代替旧的throw()异常说明。
2. 修正运算符重载的抛出语句
你当前operator+和两个operator*的错误分支都是直接抛出字符串常量:
throw("Matrices cannot be added, sizes do not match");
这种写法抛出的是const char*类型,和catch块要捕获的IllegalOperation类型完全不匹配,自然无法被捕获。需要改成抛出你定义的异常类实例,同时修正乘法分支的错误提示文案(你之前写的是不能相加,实际是不能相乘):
// operator+错误分支修正 else throw IllegalOperation("Matrices cannot be added, sizes do not match"); // 两个operator*错误分支修正 else throw IllegalOperation("Matrices cannot be multiplied, sizes do not match");
3. 修复异常类型不匹配的问题
IllegalOperation是定义在Matrix模板类内部的嵌套类,每一组不同模板参数实例化出的Matrix类,都会生成独立的IllegalOperation类型。比如Matrix<int,3,3>抛出的IllegalOperation类型是Matrix<int,3,3>::IllegalOperation,和你catch块写的Matrix<int,3,2>::IllegalOperation是完全不同的类型,3*3矩阵抛出的加法异常无法被现有catch块捕获。
两种修复方案二选一即可:
- 方案一:把
IllegalOperation类定义移到Matrix类外部,作为独立的通用异常类,所有Matrix实例都抛出同一个类型的异常 - 方案二:给catch块增加多个捕获分支,再加一个
std::exception兜底分支,示例:
catch (const Matrix<int, 3, 2>::IllegalOperation &e) { cout << e.what() << endl; } catch (const Matrix<int, 3, 3>::IllegalOperation &e) { cout << e.what() << endl; } // 兜底捕获所有继承自std::exception的异常 catch (const std::exception &e) { cout << e.what() << endl; }
额外代码逻辑问题
你写的矩阵乘法循环边界有误:j循环的终止条件现在写的是this->cols,实际应该取乘号右侧矩阵的列数N1,否则非方阵相乘时计算结果会出错。
内容的提问来源于stack exchange,提问作者Van Wilder
相关产品推荐
相关产品推荐

