Логика — Обнаружено разрушение стека C ++. Решение уравнения Лапласа

Я решаю уравнение Лапласа с использованием C ++. Я решаю для P, поле давления. В моем коде, как вы можете видеть ниже, P является функцией от x и y. Я объявил его как двумерный массив длиной nx и ny.

Окончательный результат матрицы, P, я получил, является правильным. Однако, когда я попытался напечатать эту матрицу P, используя «printf», даже если числа идеальны, я получил такую ​​ошибку:

*** 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. Любая помощь очень ценится, спасибо!

-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];
}
}

…Между прочим, я не намерен каким-либо образом избивать Фортран. На самом деле я люблю Фортран, но это другой язык (на самом деле я знаю только один, где вы начинаете индексы с 1).

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]