0

There are probably a hundred things old fashioned or inefficient about this C code. But mainly, I just want to know why I am getting a seg fault in the routine "jacobi_solve". The driver code is here:

#include <stdio.h>
#include <stdlib.h>


int main() {
  int m=20, n=20;
  int i,j;
  double A[m][n],Anew[m][n];

  for (j=0;j<n;j++){
    for (i=0;i<m;i++){
      A[j][i] = 0.; Anew[j][i] = 0.;
    }
  }

  A[10][10] = 1.;
  printf("%x\n",A); 

  jacobi_solver(A,Anew,m,n);

}

and jacobi_solver is here:

#include<stdio.h>
#include<math.h>

void jacobi_solver(double **A, double **Anew, int m, int n) {

  double err,tol=1.e-6;
  int iter=0,iter_max=100;
  int i,j;

  err = tol*10.;
  printf("hello\n");
  printf("%f %f %d %d\n",err,tol,iter,iter_max);
  printf("%x\n",A);
  printf("%f\n",A[10][10]);   /* <--- seg fault!  */
  printf("solving ...\n");

  while ( err > tol && iter < iter_max ) {

    for( j = 1; j < n-1; j++) {
      for( i = 1; i < m-1; i++) {
        Anew[j][i] = 0.25 * (A[j][i+1] + A[j][i-1] +
                             A[j-1][i] + A[j+1][i]);
        err = fmax(err, abs(Anew[j][i] - A[j][i]));
      }
    }

    printf("%f\n", err);

    for( j = 1; j < n-1; j++) {
      for( i = 1; i < m-1; i++ ) {
        A[j][i] = Anew[j][i];
      }
    }


    iter++;

  }

}

Note that if I take away the print statement, I get a seg fault later, in the main solving loop.

cadaniluk
  • 15,027
  • 2
  • 39
  • 67
bob.sacamento
  • 6,283
  • 10
  • 56
  • 115
  • 2
    `**` is a pointer to a pointer, not a pointer to a 2D array. – Unimportant Nov 13 '15 at 18:31
  • This is where I always get confused. I thought array and pointers are pretty much the same thing, and then I get told they are not. Never have really figured out the difference. Any good references? – bob.sacamento Nov 13 '15 at 18:50
  • Some good answers here: http://stackoverflow.com/questions/1335786/c-differences-between-char-pointer-and-array – Unimportant Nov 13 '15 at 18:53
  • Where is the header file for the jacobi_solver.c file ( preferably named jacobi_solver.h) – user3629249 Nov 14 '15 at 07:05
  • none of the posted code cleanly compiles, not even when the two files are merged. Strongly suggest when compiling, always enable all the warnings, then fix the warnings. (for gcc, at a minimum use: `-Wall -Wextra -pedantic` ) – user3629249 Nov 14 '15 at 07:10

2 Answers2

2

The code is incorrect - you cannot use double** the same way you use a 2-D array in C (unlike double* and 1-D array, a little confusing, but not if you understand how memory works). I suggest you implement your own 2-D array wrapper in one of the ways suggested in

How do I work with dynamic multi-dimensional arrays in C?

Community
  • 1
  • 1
Sasha Pachev
  • 5,162
  • 3
  • 20
  • 20
  • So is there any straightforward way to pass a multi-D array to a function? Or are these sorts of wrappers the only alternative? Thanks. – bob.sacamento Nov 13 '15 at 18:49
2

Change the interface of your solver function to something like

void jacobi_solver(int m, int n, double A[n][m], double Anew[n][m]) {
  ...
}

A 2D array should be just used as such. In particular is is not a table of pointers to vectors, as you had it. The array sizes have to come first, such that you can use them for the array arguments.

This should work with all compilers that are conforming to at least C99.

Jens Gustedt
  • 76,821
  • 6
  • 102
  • 177