2

I am trying in C language to use the method of bisection to find the roots of some equation, however when I try to write every step of this process in a file I get the problem "Segmentation fault". This might be an idiot fault that I did, however I have been trying to solve this for a long time. I am compiling using gcc and that is the code:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define R 1.0
#define h 1.0


double function(double a);
void attractor(double *a1, double *a2, double *epsilon);


void attractor(double *a1, double *a2, double *epsilon)
{
 FILE* bisection; 
 double a2_copia, a3, fa1, fa2;

 bisection = fopen("bisection-part1.txt", "w");
 fa1 = function(*a1);
 fa2 = function(*a2);

 if(function(*a1) - function(*a2) > 0.0)
  *epsilon = function(*a1) - function(*a2);
 else
  *epsilon = function(*a2) - function(*a1);


 fprintf(bisection, "a1     a2      fa1     fa2     epsilon\n");

 a2_copia = 0.0;

 if(function(*a1) * function(*a2) < 0.0 && *epsilon >= 0.00001)
 {
  a3 = *a2 - (*a2 - *a1);
  a2_copia = *a2;  
  *a2 = a3;

  if(function(*a1) - function(*a2) > 0.0)
   *epsilon = function(*a1) - function(*a2);
  else
   *epsilon = function(*a2) - function(*a1);

  if(function(*a1) * function(*a2) < 0.0 && *epsilon >= 0.00001)
  {
   fprintf(bisection, "%.4f %.4f %.4f %.4f %.4f\n", *a1, *a2, function(*a1), function(*a1), *epsilon); 
   attractor(a1, a2, epsilon);
  } 
  else
  {
   *a2 = a2_copia;
   *a1 = a3;
   if(function(*a1) - function(*a2) > 0)
    *epsilon = function(*a1) - function(*a2);
   else
    *epsilon = function(*a2) - function(*a1);

   if(function(*a1) * function(*a2) < 0.0 && *epsilon >= 0.00001)
   {
    fprintf(bisection, "%.4f %.4f %.4f %.4f %.4f\n", *a1, *a2, function(*a1), function(*a1), *epsilon);
    attractor(a1, a2, epsilon);
   } 
  }
 }

 fa1 = function(*a1);
 fa2 = function(*a2);

 if(function(*a1) - function(*a2) > 0.0)
  *epsilon = function(*a1) - function(*a2);
 else
  *epsilon = function(*a2) - function(*a1);

 fprintf(bisection, "%.4f %.4f %.4f %.4f %.4f\n", a1, a2, fa1, fa2, epsilon); 


}

double function(double a)
{
 double fa;
 fa = (a * cosh(h / (2 * a))) - R;
 return fa;
}

int main()
{

 double a1, a2, fa1, fa2, epsilon;


 a1 = 0.1;
 a2 = 0.5;



 fa1 = function(a1);
 fa2 = function(a2);
 if(fa1 - fa2 > 0.0)
  epsilon = fa1 - fa2;
 else
  epsilon = fa2 - fa1;

 if(epsilon >= 0.00001)
 {
  fa1 = function(a1);
  fa2 = function(a2);
  attractor(&a1, &a2, &epsilon);
  fa1 = function(a1);
  fa2 = function(a2);
  if(fa1 - fa2 > 0.0)
   epsilon = fa1 - fa2;
  else
   epsilon = fa2 - fa1;

 }

 if(epsilon < 0.0001)
  printf("Vanish at %f", a2);
 else
  printf("ERROR");



 return 0;

}

Thanks anyway and sorry if this question is not suitable.

user1286390
  • 101
  • 1
  • 2
  • 6
  • Why not print it to the console instead to isolate the problem? – Evan Mulawski Mar 22 '12 at 16:23
  • Your filename is not fully formed - you only supply the leaf name. Try supplying a fully qualified name and check that your fopen succeeds. Obviously fopen is failing since you get a segfault when you try to access the file pointer. – BitBank Mar 22 '12 at 16:27
  • The problem still happening even if I print it to the console. – user1286390 Mar 22 '12 at 16:37

2 Answers2

2

Here

fprintf(bisection, "%.4f %.4f %.4f %.4f %.4f\n", a1, a2, fa1, fa2, epsilon); 

you are passing double* parameters instead of the expected double. Should be

fprintf(bisection, "%.4f %.4f %.4f %.4f %.4f\n", *a1, *a2, fa1, fa2, *epsilon); 

instead.

Péter Török
  • 114,404
  • 31
  • 268
  • 329
1

You have too many open files. You are calling attractor recursively, and each call will open the file bisection-part1.txt. fopen returns NULL on failure. The program terminates with a segmentation fault because you are trying to use a NULL file descriptor.

You need to open the file once and pass its file descriptor to the attractor function:

void attractor(FILE *bisection, double *a1, double *a2, double *epsilon) { ... }

You should also use fclose to close all file(s) after you are done with them.

The limit on the number of open files is usually 1024. It can be printed by executing ulimit -n.


If all fprintf calls are replaced with printf, the program runs out of stack space and because of this it terminates with a segmentation fault. The program runs out of stack space because the recursion level of function attractor is too high.

  • Anyway, if I try to use printf(writing not in a file) instead of fprintf(writing in a file), segmentation fault still appearing – user1286390 Mar 22 '12 at 17:10