Reputation: 101
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.
Upvotes: 2
Views: 229
Reputation:
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.
Upvotes: 1
Reputation: 116246
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.
Upvotes: 2