c++ - openmp 段错误 - 奇怪的行为

标签 c++ openmp

总的来说,我对 C++ 和 openmp 还很陌生。我的程序的一部分在奇怪的情况下导致了段错误(至少对我来说很奇怪)。

用g++编译器不会出现,用intel编译器会出现,但是串口没有问题。

在不同的系统(大学 hpc、intel 编译器)上编译时也不会出现段错误,但在我的 PC 上会出现。

当存在三个特定的 cout 语句时,它也不会出现段错误,但是如果其中任何一个被注释掉,则会发生段错误。 (这是我觉得奇怪的地方)

我刚开始使用英特尔调试器 (idb),我还不知道如何正确使用它。但我确实设法从中获取了这些信息:

Program received signal SIGSEGV
VLMsolver::iterateWake (this=<no value>) at /home/name/prog/src/vlmsolver.cpp:996
996     moveWakePoints();

所以我将在下面展示 moveWakePoints 方法,并指出关键的 cout 行:

void VLMsolver::moveWakePoints() {

inFreeWakeStage =true;
int iw = 0;
std::vector<double> wV(3);
std::vector<double> bV(3);
for (int cl=0;cl<3;++cl) {
    wV[cl]=0;
    bV[cl]=0;
}

cout<<"thanks for helping"<<endl;

for (int b = 0;b < sNumberOfBlades;++b) {
    cout<<"b: "<<b<<endl;
    #pragma omp parallel for firstprivate(iw,b,bV,wV)
    for (int i = 0;i< iteration;++i) {
        iw = iteration -i - 1;
        for (int j = 0;j<numNodesY;++j) {
            cout<<"b: "<<b<<"a: "<<"a: "<<endl;
            double xp = wakes[b].x[iw*numNodesY+j];
            double yp = wakes[b].y[iw*numNodesY+j];
            double zp = wakes[b].z[iw*numNodesY+j];
            if ( (sFreeWake ==true && sFreezeAfter == 0) || ( sFreeWake==true && iw<((sFreezeAfter*2*M_PI)/(sTimeStep*sRotationRate)) && sRotationRate != 0  ) || ( sFreeWake==true && sRotationRate == 0 && iw<((sFreezeAfter*sChord)/(sTimeStep*sFreeStream)))) {
                if (iteration>1) { 
                    getWakeVelocity(xp, yp, zp, wV);
                }
                getBladeVelocity(xp, yp, zp, bV);
            } else {
                for (int cl=0;cl<3;++cl) {
                    wV[cl]=0;
                    bV[cl]=0;
                }
            }
            if (sRotationRate != 0) {
                double theta;
                theta = M_PI/2;
                double radius = sqrt(pow(yp,2) + pow(zp,2));
                wakes[b].yTemp[(iw+1)*numNodesY+j] = cos(theta - sTimeStep*sRotationRate)*radius;
                wakes[b].zTemp[(iw+1)*numNodesY+j] = sin(theta - sTimeStep*sRotationRate)*radius;
                wakes[b].xTemp[(iw+1)*numNodesY+j] = xp + sFreeStream*sTimeStep;
            } else { 
                std::vector<double> fS(3);
                getFreeStreamVelocity(xp, yp, zp, fS);
                wakes[b].xTemp[(iw+1)*numNodesY+j] = xp + fS[0] * sTimeStep;
                wakes[b].yTemp[(iw+1)*numNodesY+j] = yp + fS[1] * sTimeStep;
                wakes[b].zTemp[(iw+1)*numNodesY+j] = zp + fS[2] * sTimeStep;
            }
            wakes[b].xTemp[(iw+1)*numNodesY+j] = wakes[b].xTemp[(iw+1)*numNodesY+j] + (wV[0]+bV[0])*sTimeStep;
            wakes[b].yTemp[(iw+1)*numNodesY+j] = wakes[b].yTemp[(iw+1)*numNodesY+j] + (wV[1]+bV[1])*sTimeStep;
            wakes[b].zTemp[(iw+1)*numNodesY+j] = wakes[b].zTemp[(iw+1)*numNodesY+j] + (wV[2]+bV[2])*sTimeStep;

        }  // along the numnodesy
    }  // along the iterations i
    if (sBladeSymmetry) {
        break;
    }
}

顶部的三行 cout 是我添加的,当我添加时发现该程序有效。

例如,在第三行,如果我将其更改为:

cout<<"b: "<<"a: "<<"a: "<<endl;

我得到段错误,或者如果我将其更改为:

cout<<"b: "<<b<<endl; 

,我也遇到了段错误。

感谢阅读,我感谢任何想法。

最佳答案

如前一个答案所述,您可以尝试使用 Valgrind 检测内存损坏的位置。只需使用“-g -O0”编译您的二进制文件,然后运行:

valgrind --tool=memcheck --leak-check=full <binary> <arguments>

如果幸运的话,您将获得源代码中发生内存违规的确切行和列。

当添加一些“printf”语句时,段错误消失这一事实确实并不奇怪。添加这些语句,您正在修改程序拥有的内存部分。如果万一您在允许的内存部分内的错误位置写入,则不会发生段错误。

您可以引用此 pdf(“调试技术/越界”部分)以获得对该主题的更广泛解释:

Summer School of Parallel Computing

希望我对您有所帮助:-)

关于c++ - openmp 段错误 - 奇怪的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6782469/

相关文章:

c++ - 升压程序选项 : Description too wide for terminal

java - 改进计算余数的递归

c++ - 为什么 omp 并行部分中的线程不按其部分划分?

c++ - omp_set_max_active_levels() 和函数调用

c - 我是否发现了 libxml2 错误(多线程解析中的内存泄漏)?

c++ - 非方阵乘法

c++ - VirtualAlloc 失败

c++ - 基于unique_ptr参数指针类型的重载函数

c++ - 为什么复制构造函数有时要显式声明为非内联的?

OpenMP 可能无法直接并行化的代码