未报时间
No time reported
我有一个实现高斯消元法的 C++ 程序。
它在计算部分编译和运行正常,但在它应该告诉计算花费的时间之前它因段错误而崩溃。
#include <iostream>
#include <time.h>
#include <omp.h>
#include <vector>
#include <cstdlib>
using namespace std;
int main()
{
const unsigned int N = 10;
// initialize random seed:
srand (time(NULL));
vector<vector <double> > a(N, vector<double>(N+1)) ;
double buf;
vector<double> x(N);
unsigned int i,j,k;
clock_t t;
t = clock();
double prectime=omp_get_wtime();
//#pragma omp parallel for shared() private() num_threads()
//matrix and right-side vector initialisation
for(i = 0; i < N; i++)
{
for(j = 0; j < N+1; j++)
{
a[i][j]=(1+rand() % 100)/25.0;
//cout << "a[" << i << "][" << j <<"] = " << a[i][j] << endl;
}
}
//there
for(i = 0; i < N -1; i++)
{
for(j = i + 1; j < N; j++)
{
buf=a[i][i]/a[j][i];
//cout << "buf = " << buf << endl;
for (k = 0; k <= N; k++)
{
a[j][k] = a[j][k]*buf - a[i][k];
//cout << "a[" << j << "][" << k <<"] = " << a[j][k] << endl;
}
}
}
// & back again =)
x[N-1] = a[N-1][N]/a[N-1][N-1];
for(i = N-2; i >= 0; i--)
{
buf = 0;
for (j = i+1; j < N; j++)
{
buf += a[i][j] * x[j];
//cout << "buf = " << buf << endl;
}
x[i]=(a[i][N] - buf)/a[i][i];
cout << "x[" << i << "] = " << x[i] << endl;
}
prectime=omp_get_wtime()-prectime;
t=clock()-t;
cout << "The thingy is calculated in " << t << "clicks("<< ((float)t)/CLOCKS_PER_SEC <<" seconds) " << endl;
cout << "Actual time spent is probably " << prectime << "seconds "<< endl;
return 0;
}
它是用
编译的
g++ -Wall -fopenmp
,但我觉得OpenMP部分暂时可以忽略(现阶段没有用到)
我做错了什么?
编辑:如果我将 -D_GLIBCXX_DEBUG
添加到已使用的 g++
标志,它编译并运行正常,并按预期显示时间。尽管如此,仍然不能帮助我理解为什么以及出了什么问题。
unsigned int i;
for(i = N-2; i >= 0; i--)
i>=0
将始终为真,这是一个无限循环,循环体将使用无效索引 I.
访问 a[i][j]
最好将循环更改为
for(i = N-1; i-- > 0; )
您正在陷入无限循环:
for(i = N-2; i >= 0; i--)
因为 i
是一个 unsigned int
,因此当你希望它变成 -1 时,它会溢出(这意味着你错误地索引了你的数组,因为 你是越界)。结果,您没有达到计时应该出现的地步。一般来说,你应该先确定你的程序是正确的,然后再测量它的时间。
尝试将 i
设置为 int
,而不是 unsigned
。
那么哪里出了问题?
要么你的程序会运行无限,因为无限循环,
或
它会崩溃,这是最有可能发生的情况,因为 i
会取一个非常大的值(在您的系统中最大为 unsigned int
)并且会访问数组 a
无效,从而导致越界访问,这可能会导致分段错误。
通过将i
更改为int
,我们也允许i
为负数,因此它可以获得值-1,使这个答案中讨论的循环OK,因为当i
变为负数时,它不会进入循环体。
在处理无符号整数和递减计数器的 for 循环时,请始终注意溢出的危险!通常将计数器的类型更改为 unsigned int
,而不是 int
,以消除此警告:
warning: comparison between signed and unsigned integer expressions
但是,您永远不要忘记递减无符号整数应谨慎使用!
我有一个实现高斯消元法的 C++ 程序。 它在计算部分编译和运行正常,但在它应该告诉计算花费的时间之前它因段错误而崩溃。
#include <iostream>
#include <time.h>
#include <omp.h>
#include <vector>
#include <cstdlib>
using namespace std;
int main()
{
const unsigned int N = 10;
// initialize random seed:
srand (time(NULL));
vector<vector <double> > a(N, vector<double>(N+1)) ;
double buf;
vector<double> x(N);
unsigned int i,j,k;
clock_t t;
t = clock();
double prectime=omp_get_wtime();
//#pragma omp parallel for shared() private() num_threads()
//matrix and right-side vector initialisation
for(i = 0; i < N; i++)
{
for(j = 0; j < N+1; j++)
{
a[i][j]=(1+rand() % 100)/25.0;
//cout << "a[" << i << "][" << j <<"] = " << a[i][j] << endl;
}
}
//there
for(i = 0; i < N -1; i++)
{
for(j = i + 1; j < N; j++)
{
buf=a[i][i]/a[j][i];
//cout << "buf = " << buf << endl;
for (k = 0; k <= N; k++)
{
a[j][k] = a[j][k]*buf - a[i][k];
//cout << "a[" << j << "][" << k <<"] = " << a[j][k] << endl;
}
}
}
// & back again =)
x[N-1] = a[N-1][N]/a[N-1][N-1];
for(i = N-2; i >= 0; i--)
{
buf = 0;
for (j = i+1; j < N; j++)
{
buf += a[i][j] * x[j];
//cout << "buf = " << buf << endl;
}
x[i]=(a[i][N] - buf)/a[i][i];
cout << "x[" << i << "] = " << x[i] << endl;
}
prectime=omp_get_wtime()-prectime;
t=clock()-t;
cout << "The thingy is calculated in " << t << "clicks("<< ((float)t)/CLOCKS_PER_SEC <<" seconds) " << endl;
cout << "Actual time spent is probably " << prectime << "seconds "<< endl;
return 0;
}
它是用
编译的g++ -Wall -fopenmp
,但我觉得OpenMP部分暂时可以忽略(现阶段没有用到)
我做错了什么?
编辑:如果我将 -D_GLIBCXX_DEBUG
添加到已使用的 g++
标志,它编译并运行正常,并按预期显示时间。尽管如此,仍然不能帮助我理解为什么以及出了什么问题。
unsigned int i;
for(i = N-2; i >= 0; i--)
i>=0
将始终为真,这是一个无限循环,循环体将使用无效索引 I.
a[i][j]
最好将循环更改为
for(i = N-1; i-- > 0; )
您正在陷入无限循环:
for(i = N-2; i >= 0; i--)
因为 i
是一个 unsigned int
,因此当你希望它变成 -1 时,它会溢出(这意味着你错误地索引了你的数组,因为 你是越界)。结果,您没有达到计时应该出现的地步。一般来说,你应该先确定你的程序是正确的,然后再测量它的时间。
尝试将 i
设置为 int
,而不是 unsigned
。
那么哪里出了问题?
要么你的程序会运行无限,因为无限循环,
或
它会崩溃,这是最有可能发生的情况,因为 i
会取一个非常大的值(在您的系统中最大为 unsigned int
)并且会访问数组 a
无效,从而导致越界访问,这可能会导致分段错误。
通过将i
更改为int
,我们也允许i
为负数,因此它可以获得值-1,使这个答案中讨论的循环OK,因为当i
变为负数时,它不会进入循环体。
在处理无符号整数和递减计数器的 for 循环时,请始终注意溢出的危险!通常将计数器的类型更改为 unsigned int
,而不是 int
,以消除此警告:
warning: comparison between signed and unsigned integer expressions
但是,您永远不要忘记递减无符号整数应谨慎使用!