堆栈粉碎检测到C ++。解拉普拉斯方程

时间:2017-05-16 07:37:22

标签: c++ logic stack-smash

我正在使用C ++解决拉普拉斯方程。我正在为压力场P求解。在我的代码中,您可以看到下面,P是x和y的函数。我将它声明为长度为nx和ny的2d数组。

我得到的最终矩阵结果是正确的。但是,当我尝试使用“printf”打印这个矩阵P时,尽管数字很完美,但我得到了这样的错误:

*** stack smashing detected ***
/bin/bash: line 1: 11738 Aborted  

以下是我的计划:

#include <cmath>
#include <stdio.h>
const int nx = 5; // number of elements in x-direction
const int ny = 5; // number of elements in x-direction
const int niter = 100; //# of iterations 

int main(){
    double dx = 2/double((nx-1)); 
    double dy = 1/double((ny-1));
    int xmax = 2; int xmin = 0;
    int ymax = 1; int ymin = 0;
    double p[nx][ny];
    double pn[nx][ny];
    double x[nx];
    double y[ny];

    //populate p with zeros     
    for (int xi = 1; xi <=nx;xi++){
        for (int yi = 1;yi<=ny;yi++){
            p[xi][yi] = 0;          
        }
    }

    //populate x and y

    //X
    for (int xnum = 1; xnum <=nx; xnum++){
        x[1] = 0;
        x[xnum+1] = x[xnum] + dx;
    }

    //Y
    for (int ynum = 1; ynum <=ny; ynum++){
        y[1] = 0;
        y[ynum+1] = y[ynum] + dy;
    }

    //initial condition

    for (int yrange = 1; yrange<=ny;yrange++){
        p[nx][yrange] = y[yrange];
    }

    //SOLVING FOR P     

    for (int iter = 1; iter<=niter; iter++){
        //copy values
        for (int xiter= 1; xiter<=nx;xiter++){
            for (int yiter = 1; yiter<=ny;yiter++){
                pn[xiter][yiter]=p[xiter][yiter];
            }
        }
        //main loop
        for (int i = 2; i<=nx-1;i++){
            for (int j = 2; j<=ny-1;j++){
                p[i][j] = ((pow(dy,2)*(pn[i+1][j]+pn[i-1][j]))+(pow(dx,2)*(p[i][j+1]+pn[i][j-1])))/(2*(pow(dx,2)+pow(dy,2)));
            }
        }

        for (int xrange = 2; xrange<=nx-1;xrange++){
            p[xrange][1] = p[xrange][2];
            p[xrange][ny] = p[xrange][ny-1];
        }

    }

    //Testing matrix

        for (int x = 1; x<=nx;x++){
            for (int y =1; y<=ny;y++){
            printf("%1.3f\t",p[x][y]);
            }
        printf("\n");
        }

return 0;
}

起初,我认为这是迭代次数太高的问题。换句话说,氮气太高,所以我决定降低它。不过,我得到了同样的错误。你能帮我一下吗?矩阵P的输出结果是正确的,所以我不认为这是解决P的逻辑。任何帮助都非常感谢,谢谢!

1 个答案:

答案 0 :(得分:2)

你的循环一直到nx这是未定义的行为,因为你正在访问越界。索引从0开始直到i < nx

此:

for (int xi = 1; xi <= nx; xi++){
    for (int yi = 1; yi <= ny; yi++){
        p[xi][yi] = 0;          
    }
}

应该是

for (int xi = 0; xi < nx; xi++){
    for (int yi = 0; yi < ny; yi++){
        p[xi][yi] = 0;          
    }
}

和所有其他循环相同。 你的程序似乎进展顺利,可能会在某些与UB原因明显无关的地方崩溃。当你有未定义的行为时,任何事情都可能发生(包括什么都没有,所以实际上你很高兴你得到了崩溃并且有机会修复它)。

PS:如果你真的想要(不知道为什么,也许你是FORTRAN的奉献者),你可以在1开始你的循环。但是,我不建议这样做,因为它会使你的循环不必要地难以阅读和错误易于。例如,以下循环中的错误很容易被忽略:

    //copy values (!!! WRONG CODE !!! spot the error to win a FORTRAN fanshirt)
    for (int xiter= 1; xiter < nx+1; xiter++){
        for (int yiter = 1; yiter < ny+1; yiter++){
            pn[xiter-1][yiter-1] = p[xiter][yiter-1];
        }
    }

...顺便说一句,我不打算以任何方式抨击FORTRAN。事实上我喜欢FORTRAN,但它是一种不同的语言(实际上我唯一知道你在哪里开始索引)。