2017-06-23 8 views
0

ポイント間の距離のマトリックスを作成するプログラムを持っています(私のテストファイルでは、3D空間に〜8000ポイントあります)。だから私は(約)8000x8000の行列が欲しいですが、私は倍数(または浮動小数点数)の配列を使用して構築しようとすると、私はいつも 'セグメンテーションフォールト(コアダンプ)'エラーが発生します。なぜどんなアイデア?私は16GBのRAMを持っているので、8000 * 8000 * 8はおよそ0.5GBなので、これは実行可能でなければなりません。また、(以下のコードでコメントアウト)、ベクトルのベクトルとして行列を構築できますが、これは遅いです(約30秒かかります)。それが起こると、私は1.5未満の距離を記録すればよいので、行列は非常に疎です。より良い実装方法があるのは間違いありませんが、これはうまくいかないと私に迷惑をかけています。どんなアドバイスもありがとうございました!C++ 2d arrayはセグメンテーションフォールト(コアダンプ)

//Get distance matrix from .dms file 
#include <iostream> 
#include <stdlib.h> 
#include <fstream> 
#include <string> 
#include <cmath> 
#include <vector> 

using namespace std; 

double dist(vector<double> a, vector<double> b) { 
    if (a.size() != b.size()) return -1; 
    else 
    { 
     double dist = 0; 
     for (int i = 0; i < a.size(); i++) dist += pow(a[i] - b[i], 2); 
     return dist; 
    } 
} 

int main() { 
    ifstream infile; 
    ofstream outfile; 
    vector<vector<double> > points; 
    string line; 
    infile.open("1dwr.dms"); 
    outfile.open("1dwr.mat"); 
    while (getline(infile,line)) 
    { 
     if ((line.at(line.length() - 1)) != 'A') 
     { 
      double x[3] = {atof((line.substr(13,8)).c_str()), atof((line.substr(21,9)).c_str()), atof((line.substr(30,9)).c_str())}; 
      vector<double> point; 
      for (int i=0; i<3; i++) 
      { 
       point.push_back(x[i]); 
      } 
      points.push_back (point); 
     } 
    } 
    infile.close(); 
    int len = points.size(); 
    double dist_matrix[len][len]; 

    for (int i=0; i<len; i++) 
    { 
     for(int j=i; j<len; j++) 
     { 
      double d = dist(points[i], points[j]); 
      if(d < 2.25) 
      { 
       dist_matrix[i][j] = sqrt(d); 
       dist_matrix[j][i] = sqrt(d); 
      } 
     } 
    } 

// vector<vector<double> > dist_matrix; 
// for (int i=0; i<len; i++) 
// { 
//  vector< double> row; 
//  for (int j=0; j<len; j++) 
//  { 
//   double d = dist(points[i], points[j]); 
//   if (d < 2.25) row.push_back (sqrt(d)); 
//   else row.push_back (0); 
//  } 
//  dist_matrix.push_back (row); 
// } 


    outfile.close(); 
    return 0; 
} 
+2

デバッガ。スタックオーバーフローを尋ねる前に、コードを一行ずつ進める必要があります。詳しいヘルプは、[小さなプログラムをデバッグする方法(Eric Lippert)](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/)を参照してください。少なくとも、問題を再現する[最小、完全、および検証可能](http://stackoverflow.com/help/mcve)の例と、デバッガでの観察結果を含めるように質問を編集する必要があります。 –

+0

ありがとうございます。失敗するステップは変数 'double dist_matrix [len] [len]'を宣言しており、変数 'len'が大きすぎるため失敗します。 – user3552101

+0

おそらくスタックオーバーフロー! –

答えて

2

問題文はint len = points.size(); double dist_matrix[len][len]プログラムはスタックにダブルスの8000 x 8000 -arrayを作成することができますし、スタックの大きさがあるということです - ヒープに比べて - かなり限られました。したがって、スタックオーバーフローが発生している可能性が高く、おそらく「不正アクセス」エラーが発生している可能性があります。 80x80でコードを試してみると、おそらく動作します。

len==8000の場合は、ヒープ上に配列を作成する必要があります。コンパイル時にlenがわからない場合は、私の知る限り、double x[len][len] = new double...のようなステートメントを実行する方法はありません。

以下のコードに示すように、手動で-indexサイズ len * lenの1Dアレイを割り当てることにより、この周囲に来ると「2D」を計算することができる

:このような問題を解決するための適切なツールはあなたです

int main() { 

    int len = 8000; 
    double *dist_matrix = new double[len*len]; 

    for (int i=0; i<len; i++) 
    { 
     for(int j=i; j<len; j++) 
     { 
      size_t idx = len*i + j; 
      dist_matrix[idx] = 5.0; 
     } 
    } 
    return 0; 

} 
+0

上記の便利なラッパーのデモンストレーションとしてこのリンクをドロップしてください:https://isocpp.org/wiki/faq/operator-overloading#matrix-subscript-op – user4581301

+0

Thanks Stephanそのアプローチは、πάνταῥεῖの提案に従ったベクトルのベクトルを使用するのと同じ速度(約15秒)を与えます。私はまだタイミングが遅いと思っています - 計算するには10^8の距離がありますが、私のプロセッサは私に7 * 10^10 FLOPSを与えることができるはずです... – user3552101

関連する問題