c ++ 2d数组导致分段错误(核心转储)

时间:2017-06-23 21:03:57

标签: c++ arrays matrix

我有一个程序(下面)来构建点之间的距离矩阵(在我的测试文件中,3D空间中有大约8000个点)。所以我想要(大致)8000x8000矩阵,但是当我尝试使用双精度数组(或浮点数)来构建它时,我总是得到一个“分段错误(核心转储)'错误。有什么想法吗?我有16GB的RAM,所以这应该是可行的,因为8000 * 8000 * 8只有大约0.5GB。另外(在下面的代码中注释),我可以将矩阵构建为向量的向量,但这很慢 - 大约需要30秒。碰巧的是,我只需要记录小于1.5的距离,因此矩阵非常稀疏 - 毫无疑问有更好的实现方法,但是我不知道这不起作用。任何建议都感激不尽!

//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;
}

1 个答案:

答案 0 :(得分:2)

问题是语句int len = points.size(); double dist_matrix[len][len]允许程序在堆栈上创建一个8000 x 8000 - 双数组,并且堆栈的大小与堆相比 - 相当有限。所以你很可能得到一个#34;堆栈溢出&#34;,可能是由一个&#34; Bad access&#34; -error指示的。如果您使用80x80尝试使用代码,则可能会有效。

因此,对于len==8000,您必须在堆上创建数组;但据我所知 - 如果在编译时不知道double x[len][len] = new double...,就无法做len这样的陈述。

您可以通过分配大小为len * len的1D数组并手动计算&#34; 2D&#34; -index来实现此目的,如下面的代码所示:

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;

}