2012-03-22 40 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が成功したことを確認してください。明らかに、ファイルポインタにアクセスしようとするとsegfaultが発生するため、fopenは失敗しています。 – BitBank

+0

コンソールに印刷してもまだ問題が発生しています。 – user1286390

答えて

1

開いているファイルが多すぎます。 attractorを再帰的に呼び出すと、各呼び出しでファイルbisection-part1.txtが開きます。 fopenは、失敗した場合にNULLを返します。 NULLファイル記述子を使用しようとしているため、プログラムはセグメント化エラーで終了します。また、あなたは彼らと一緒に行われた後、すべてのファイルを閉じるにはfcloseを使用する必要があります

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

あなたは一度ファイルを開いてattractor関数にそのファイルディスクリプタを渡す必要があります。

開いているファイルの数の制限は、通常1024です。ulimit -nを実行すると印刷できます。


すべてfprintfコールがprintfに置き換えている場合は、プログラムはスタック領域が不足し、このために、それは、セグメンテーションフォールトで終了します。関数attractorの再帰レベルが高すぎるため、スタック領域が不足しています。

+0

とにかく、fprintf(ファイルに書き込む)の代わりにprintf(ファイルに書き込まない)を使用しようとすると、まだセグメンテーションフォルトが – user1286390

+0

でもOKです。私は自分の答えを更新しました。 –

2

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

あなたの代わりに期待doubledouble*パラメータを渡しています。代わりに

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

である必要があります。

+0

申し訳ありませんが、floatの代わりにdoubleを使用しようとしたときに "lf"を変更するのを忘れました。とにかく、ダブルまたはフロートを使用して、問題は "セグメンテーションフォールト"が表示されます。 – user1286390

+0

@ user1286390、「lf」は必要ないと思われるので、私はさらなる研究の後で私の投稿を更新しました。「f」は「double」を表します。 –

+0

申し訳ありませんが、問題はまだ発生しています。 – user1286390

関連する問題