Mauro Mauro - 9 days ago 4
C++ Question

Segmentation fault because of the array size?

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

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.