0

我正在编写一个基于表达式模板(元编程)的 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]; }
        };
4

1 回答 1

1
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_));

这里分配的内存不足,因为除了所有字符串之外,格式字符串还包含空格 \ns 和终端零。虽然 Double_new_line 被计算为 \n\n 空格和终端零仍然存在。
还有为什么使用malloc而不是new?甚至更好std::string?由于我看不到任何空闲,这将导致内存泄漏。

于 2013-04-23T21:32:15.920 回答