异常已处理,但被捕获后程序中止 我正在编写一个基于表达式模板(元编程)的C++库。

异常已处理,但被捕获后程序中止 我正在编写一个基于表达式模板(元编程)的C++库。,c++,exception,metaprogramming,C++,Exception,Metaprogramming,我有一个矩阵类,我还实现了一个子矩阵类来提取矩阵的一部分。我已经为赋值具有不同操作数大小的情况下的赋值=操作符设置了异常处理,现在我正在为子矩阵索引与原始矩阵不匹配的情况下的子矩阵提取设置异常处理。我已验证分配=的异常处理是否正常工作 子矩阵提取的语法如下 B=SubMatrix(A,a,b,c,d); 其中具有以下Matlab等效项 B=A(a:b,c:d); 当我尝试 Matrix<double> A_H(3,4); Matrix<double>

我有一个
矩阵
类,我还实现了一个
子矩阵
类来提取矩阵的一部分。我已经为赋值具有不同操作数大小的情况下的赋值
=
操作符设置了异常处理,现在我正在为子矩阵索引与原始矩阵不匹配的情况下的子矩阵提取设置异常处理。我已验证分配
=
的异常处理是否正常工作

子矩阵
提取的语法如下

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; } 
有人有解释吗?子矩阵的异常处理与赋值的异常处理之间是否存在“干扰”?提前感谢您的帮助

编辑-捕获异常的功能

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__); 
            } 
}
编辑-MALLOC和虚拟函数

#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
存在问题。无论如何,我也尝试过使用
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]; }
        };
此处分配的内存不足,因为除所有字符串外,格式化字符串还包含空格\n和端子零。当双\u新\u行被计算为\n \n空格和终端零仍然保留时。

为什么使用
malloc
而不是
new
?或者更好的
std::string
?由于我看不到任何空闲,这将导致内存泄漏。

您能为整个函数提供代码吗?您是指
子矩阵
类还是
异常
类还是其他?我指的是处理错误的整个函数。不仅仅是try/catch的一部分使用捕获异常的函数编辑了文章。这里只有throw,您不需要在模板中使用所有这些。不幸的是,我已经验证了这不是我问题的原因。我会更好地检查并提供进一步的评论,如果我有评论的话。关于内存泄漏,只有在发现异常并且程序终止后,才会分配
catString
内存。这真的是个问题吗?
        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]; }
        };
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_));