2016-10-28 2 views
0

2つの別々のファイルから2つの行列を読み込むC++プログラムを書いています。最終的にこれらの行列を使って処理を行いますが、今はコマンドラインオプションを解析する際に問題があります。これがデータの提示方法です。同じ引数を解析しているときにsegfault

があるカップル異なるコマンドラインは、バリアント:

DTYPE NをFILE1 FILE2 FILE3

DTYPE NML FILE1 FILE2 FILE3

ちょうどNがすべて提示されている場合DTYPEは、intまたは二重のいずれかになります

行列はNxNであり、そうでない場合、行列1はNxMであり、行列2はMxLであり、ファイル1と2には操作対象の行列が含まれ、ファイル3には結果が格納されます。

私はこれまでに書いた内容を含めました。私はC + +の初心者ですので、あなたの批判にあまりにも厳しくしないでください。

このコードを実行すると、問題が発生する可能性がありますが、segfaultであれば完全にランダムに見えます。セグメンテーションの問題を解決するために後部の痛みがあるかもしれないことは分かっていますが、私はここで他の質問を見ていますが、文字通り他の選択肢はありませんが、

問題を解決するにはg ++を-gオプション付きでコンパイルし、プログラムをgdbで実行しました。私はsegfaultをgdbで複製できませんでした。

#include <iostream> 
#include <string> 
#include <string.h> 
#include <vector> 
#include <fstream> 
#include <typeinfo> 
#include <sys/stat.h> 
#include <stdexcept> 

using namespace std; 

inline bool exists_test(const std::string& name) { 
    struct stat buffer; 
    return (stat (name.c_str(), &buffer) == 0); 
} 

int main(int argc, char const *argv[]) 
{ 

    int dtype = 0; // 0 = int; 1 = double 
    int M = 0; 
    int N = 0; 
    int L = 0; 
    const char *file1; 
    const char *file2; 
    const char *file3; 

    for (int i=1; i<argc ; i++) 
    {  
     try 
     { 
      if(i==1){ 
       if(!((strcmp(argv[1], "int") == 0) || (strcmp(argv[1], "double") == 0))){ 
        throw invalid_argument("wrong dtype"); 
       }else{ 
        if((strcmp(argv[1], "double") == 0)){ 
         dtype = 1; 
        } 
       } 
      }else if(i==2){ 
       M=stoi(argv[i]); 
      }else if(i==3){ 
       if(!exists_test(argv[i])){ 
        N=stoi(argv[i]); 
       }else{ 
        file1 = argv[i]; 
       } 
      }else if(i==4){ 
       if(!exists_test(argv[i])){ 
        L=stoi(argv[i]); 
       }else{ 
        file2 = argv[i]; 
       } 
      }else if(i==5 || i==6 || i==7){ 
       if(!exists_test(argv[i])){ 
        throw invalid_argument("no such file"); 
       }else{ 
        if(i==6){ 
         file2 = argv[i]; 
        }else if(i==7){ 
         file3 = argv[i]; 
        }else if(strcmp(file1, argv[i]) == 0){ 

        }else{ 
         file1 = argv[i]; 
        } 
       } 
      } 
      continue; 
     } 
     catch (...) 
     { 
      cout << "error code 1 or this one" << endl; 
      return 1; 
     } 
    } 

    if(N==0){ 
     N=M; 
    } 
    if(L==0){ 
     L=M; 
    } 

    ifstream thisfile; 

    double filler = 0; 
    vector<double> readThese; 
    vector< vector<double> > matrixA(4, vector<double>(3, 0)); 

    thisfile.open(file1); 

    while (thisfile >> filler) 
    { 
     readThese.push_back(filler); 
    } 

    thisfile.close(); 

    //for(int j = 0; j < N; j++){ 
    // matrixA[0][j] = readThese[j]; 
    //} 

    cout << matrixA[0][0] << " " << matrixA[0][1] << " " << matrixA[0][2] << " " << matrixA[0][3] << endl; 
    cout << matrixA[1][0] << " " << matrixA[1][1] << " " << matrixA[1][2] << " " << matrixA[1][3] << endl; 
    cout << matrixA[2][0] << " " << matrixA[2][1] << " " << matrixA[2][2] << " " << matrixA[2][3] << endl; 
    cout << matrixA[3][0] << " " << matrixA[3][1] << " " << matrixA[3][2] << " " << matrixA[3][3] << endl; 
} 

以下は、プログラムの出力を示しています。それはいつも別の時間にセグメンテーションするとは限りません。

$ ./a.out int 3 4 1 file1 file2 
0 0 0 1.63042e-322 
0 0 0 1.63042e-322 
0 0 0 1.63042e-322 
0 0 0 5.14322e-321 
$ ./a.out int 3 4 1 file1 file2 
Segmentation fault (core dumped) 
$ ./a.out int 3 4 1 file1 file2 
0 0 0 1.63042e-322 
0 0 0 1.63042e-322 
0 0 0 1.63042e-322 
0 0 0 5.14322e-321 
$ ./a.out int 3 4 1 file1 file2 
Segmentation fault (core dumped) 
+0

segfaultを取得することは、コード内のどこかにUBを示すことがありますが、必ずしもsegfaultにはなりません。 –

答えて

2

あなたは4×3行列を表したが、その後inexistentですので、あなたがセグメンテーション違反を得る4番目の列

cout << matrixA[0][0] << " " << matrixA[0][1] << " "\ 
    << matrixA[0][2] << " " << matrixA[0][3] << endl; 
           ^^^^^^^^^^^^^ 
            here 

にアクセス

matrixA(4, vector<double>(3, 0)); 

を宣言します。範囲外をテストするには、std::vector::operator[]ではなくstd::vector::at()を使用できますが、範囲外にアクセスすると遅くなりますが、std::out_of_range例外がスローされます。コードが正常であることを確認したら、operator[]に戻すことができます。

ところで、一般に、vector<vector>として行列を表すことは悪い考えです。単一のベクタが要素が連続的にメモリに格納されていることを保証するため、1つのベクトルと1Dから2次元座標へのマップ、またはその逆のマッピングを使用する方が良い方法です。

+0

さて、今私は馬鹿のように感じません。 – user1362058

+0

どのようにして、より大きな行列を単一の次元で追跡することができますか?マッピングは複雑になりますか?私は参照を見つけることができる場合は表示されます。 – user1362058

+0

@ user1362058行列がROWS x COLSの場合、マップは '(i、j) - > COLS * i + j'です。逆のマップは 'm - >(m/COLS、m%COLS)'と思います。 – vsoftco

関連する問題