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();に aを追加してビデオ出力を残酷にフリーズすることで、正しい例外がキャッチされることを確認しました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 に答える