Mauro - 11 months ago 62

C++ Question

I've been doing a really really simple finite difference code that solves the 1D convection equation.

It seems to work pretty fine but if I increase the size of the arrays that I'm using I get a segmentation fault error. This happens when I reduce the timestep or if I increase the time interval.

The code is

`#include <math.h>`

#include <iostream>

#include <fstream>

#include <stdio.h>

#include <cmath>

using namespace std;

int main(){

double xi = 0.0;

double xf = 10.0;

double ti = 0.0;

double tf = 1.0;

Time interval, if it is equal to 1 the code works fine.

`double x,t;`

double dt = 0.1;

double dx = 0.1;

int nstep_x = (xf - xi)/dx;

int nstep_t = (tf - ti)/dt;

double f[nstep_x][nstep_t];

double ex[nstep_x][nstep_t];

// Parameters

const double v = 0.05;

const double D = 0.0001;

const double pi = 3.141592654;

ofstream salida;

salida.open("out");

for (int i = 0 ; i <= nstep_x; i++){

x = xi + dx*i;

f[i][0] = 0.5*sin(pi*x); //Initial conditions

salida << x << " " << 0 << " " << f[i][0] << endl;

}

salida << endl;

for (int n = 0; n <= nstep_t ; n++){

t = ti + n*dt;

for (int i = 1; i <= nstep_x; i++){

x = xi + dx*i;

f[i][n+1] = f[i][n] - ((v*dt)/(2*dx))*(f[i+1][n] - f[i-1][n]); //CONV|SOC

ex[i][n] = 0.5*sin(pi*x - v*t);

salida << x << " " << t << " " << ex[i][n] << " " << f[i][n] << endl;

}

salida << endl;

salida << endl;

}

}

I think that is not a problem of going out of the array bounds in the loops because the code works for "small" arrays.

I guess that I must be doing something wrong with the array handling but I can't find the error.

Answer Source

As noted in the comments, the reason is not the array size, but the for loops

```
for (int i = 0 ; i <= nstep_x; i++) {
// ...
f[i][0] = 0.5*sin(pi*x);
}
```

This is a classic one off error, going one beyond the end of the array. The correct way is

```
for (int i = 0 ; i < nstep_x; i++) {
// ...
}
```

Note `<`

vs `<=`

.

```
for (int n = 0; n <= nstep_t ; n++) {
for (int i = 1; i <= nstep_x; i++) {
// ...
f[i][n+1] = f[i][n] - ((v*dt)/(2*dx))*(f[i+1][n] - f[i-1][n]);
}
}
```

Here too, you have `<=`

instead of `<`

. Additionally you access indexes at `i + 1`

and `n + 1`

respectively, which means, you are not one but two steps over the end of the array.