我正在编写一个基于表达式模板(元编程)的 C++ 库。
我有一个Matrix
类,我还实现了一个SubMatrix
类来提取矩阵的一部分。我已经为赋值=
运算符设置了异常处理,以处理赋值具有不同操作数大小的情况,现在我正在为子矩阵索引与原始矩阵不匹配的情况下的子矩阵提取设置异常处理. 我已验证分配的异常处理=
工作正常。
提取的语法SubMatrix
如下
B=SubMatrix(A,a,b,c,d);
它具有以下 Matlab 等价物
B=A(a:b,c:d);
当我尝试
Matrix<double> A_H(3,4);
Matrix<double> B_H(3,2);
try { B_H = SubMatrix(A_H,0,1,1,2); } catch(exception &e) { cout << e.what() << endl; return; }
的正确异常SubMatrix
被捕获,但程序随后立即中止。我已经验证了正确的异常是通过添加一个getch();
to 来粗暴地冻结视频输出try-catch
,即
try { B_H = SubMatrix(A_H,0,1,1,2); } catch(exception &e) { cout << e.what() << endl; getch(); return; }
有人有解释吗?SubMatrix
的异常处理和分配的异常处理之间是否有任何“干扰” =
?预先感谢您的任何帮助。
编辑 - 捕获异常的功能
template<class T>
Expr<SubMatrixExpr<const T*,T>,T> SubMatrix(const Matrix<T>&v,const int a,const int b,const int c,const int d)
{ if((a >= 0) && (a < v.GetRows()) && (a <= b) && (b >= 0) && (b < v.GetRows()) &&
(c >= 0) && (c < v.GetColumns()) && (c <= d) && (d >= 0) && (d < v.GetColumns()))
{
typedef SubMatrixExpr<const T*,T> SExpr;
return Expr<SExpr,T>(SExpr(v.GetDataPointer(),v.GetRows(),v.GetColumns(),a,b,c,d),b-a+1,d-c+1);
} else { char* str0 = "************************************\n";
char* str1 = "* CPU SubMatrix indices must match *\n";
char* str2 = "Matrix size: ";
char* str3 = "SubMatrix indices (a,b,c,d): ";
char* catString = (char*) malloc(2*strlen(str0)+strlen(str1)+strlen(str2)+strlen(str3)+50*sizeof(char));
sprintf(catString, "%s%s%s\n%s%i x %i\n%s(%i,%i,%i,%i)\n",str0,str1,str0,str2,v.GetRows(),v.GetColumns(),str3,a,b,c,d);
throw GenericError(catString,__FILE__,__LINE__);
}
}
编辑 - 异常处理类
#define Error_msg_1 "Error in file"
#define Double_new_line "\n\n"
#define Error_msg_2 "on line"
class LibraryException: public std::exception
{
private:
const char *message_;
const char *file_;
int line_;
protected:
LibraryException(const char *message, const char* file, int line): message_(message), file_(file), line_(line) {}
public:
int get_line() const { return line_; }
const char* get_file() const { return file_; }
virtual const char* what() const throw()
{
char buf[20];
sprintf(buf, "%d", line_);
char* catString = (char*) malloc(strlen(Error_msg_1)+strlen(Double_new_line)+strlen(file_)+strlen(Double_new_line)+strlen(Error_msg_2)+strlen(buf)+strlen(message_));
sprintf(catString, "%s \n\n%s\n\n%s %s\n\n%s", Error_msg_1,file_,Error_msg_2,buf,message_);
return catString; }
};
class GenericError: public LibraryException
{
public:
GenericError(const char *message, const char* file, int line) :
LibraryException(message, file, line) {}
};
编辑 - MALLOC 和虚拟功能
从帖子malloc() 和虚函数到底有什么问题?,就出现了malloc
在虚函数中使用的问题。无论如何,我也尝试过使用new
,但问题仍然存在,我已经检查过我无法在virtual
函数中动态分配任何东西。此外,这个问题是“间歇性的”,有时会发生,有时不会。最后,我用这样的静态分配解决了这个问题
virtual const char* what() const throw()
{
char buf[20];
sprintf(buf, "%d", line_);
char catString[2048];
sprintf(catString, "%s \n\n%s\n\n%s %s\n\n%s", Error_msg_1,file_,Error_msg_2,buf,message_);
return &catString[0]; }
};