我有一个程序(下面)来构建点之间的距离矩阵(在我的测试文件中,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;
}
答案 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;
}