Сегментация файлов при попытке записи в файл - PullRequest
2 голосов
/ 22 марта 2012

Я пытаюсь на языке Си использовать метод деления пополам, чтобы найти корни некоторого уравнения, однако, когда я пытаюсь записать каждый шаг этого процесса в файл, я получаю проблему «Ошибка сегментации».Это может быть идиотская ошибка, которую я сделал, однако я пытался решить эту проблему в течение долгого времени.Я компилирую с использованием gcc, и это код:

#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;

}

В любом случае спасибо и извините, если этот вопрос не подходит.

Ответы [ 2 ]

2 голосов
/ 22 марта 2012

Здесь

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

вы передаете double* параметры вместо ожидаемых double. Должно быть

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

вместо.

1 голос
/ 22 марта 2012

У вас слишком много открытых файлов. Вы вызываете attractor рекурсивно, и каждый вызов открывает файл bisection-part1.txt. fopen возвращает NULL при ошибке. Программа завершается с ошибкой сегментации, потому что вы пытаетесь использовать дескриптор файла NULL.

Вам нужно один раз открыть файл и передать его дескриптор файла в функцию attractor:

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

Вы также должны использовать fclose, чтобы закрыть все файлы после того, как с ними покончено.

Ограничение на количество открытых файлов обычно составляет 1024. Его можно распечатать, выполнив ulimit -n.


Если все вызовы fprintf заменены на printf, программе не хватает места в стеке, и из-за этого она завершается ошибкой сегментации. Программе не хватает места в стеке, поскольку уровень рекурсии функции attractor слишком высок.

...