2012-03-22 3 views
2

Я пытаюсь на языке C использовать метод деления пополам, чтобы найти корни некоторого уравнения, однако, когда я пытаюсь написать каждый шаг этого процесса в файле, я получаю проблему «Ошибка сегментации». Это может быть идиотской ошибкой, что я и сделал, однако я пытался это решить в течение длительного времени. Я компилирую с использованием 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; 

} 

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

+0

Почему бы не напечатать его на консоли, чтобы изолировать проблему? –

+0

Ваше имя не сформировано полностью - вы указываете только имя листа. Попробуйте предоставить полное имя и убедитесь, что ваш fopen преуспел. Очевидно, fopen терпит неудачу, так как вы получаете segfault при попытке получить доступ к указателю файла. – BitBank

+0

Проблема все еще происходит, даже если я печатаю ее на консоли. – user1286390

ответ

1

У вас слишком много открытых файлов. Вы вызываете 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 слишком высок.

+0

В любом случае, если я пытаюсь использовать printf (записывая не в файл) вместо fprintf (запись в файл), ошибка сегментации все еще появляется – user1286390

+0

ОК. Я обновил свой ответ. –

2

Здесь

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

вместо этого.

+0

Извините, я забыл изменить «lf», когда попытался использовать double вместо float. Во всяком случае, используя double или float, проблема «Ошибка сегментации» все еще появляется. – user1286390

+0

@ user1286390, я обновил свой пост после дальнейших исследований, так как кажется, что «lf» не требуется - «f» означает «double». –

+0

Извините, но проблема все еще происходит. – user1286390

Смежные вопросы