未报时间

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

但是,您永远不要忘记递减无符号整数应谨慎使用!