質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.52%

  • C

    3670questions

    C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

  • Windows 7

    370questions

    Microsoft Windows 7は過去にリリースされたMicrosoft WindowsのOSであり、Windows8の1代前です。2009年の7月にリリースされ販売されました。Windows7の前はWindowsVistaで、その更に3年前にリリースされました。

c言語のプログラムを実行すると強制終了してしまう

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 220

S.Abe

score 2

 前提・実現したいこと

win7のgcc環境において、以下のプログラムでルンゲクッタ法による数値計算を行おうとしています。gccでのデバッグは問題ないのですが、プログラムを実行すると強制終了を起こしてしまいます。原因が特定できていませんので、修正方法をご教授頂きたいです。

#include <stdio.h>
#include <math.h>

double f1(double t,double u,double v);
double f2(double t,double u,double v);

int main(void) {
    FILE *output;
    output = fopen("output.dat","w");

    double t = 0.0;
    double dt = 0.01;
    double delta = 0.1;
    double r[3000][3000];
    double u = 1.0, w = 1.0;//初期値
    double a=0.03, b=0.10;//論文での値
    double k0[2][2], k1[2][2], k2[2][2], k3[2][2];//計算した値を入れる配列

    //離散化を構成する
    int i;
    int n,s,p;//mpとmqの添え字
    double mp,mq;
    double u2[3000][3000];
    double w2[3000][3000];
    //double u2[0][0]=0.0;//初期化
    //double w2[0][0]=0.0;//初期化
    u2[s][n]=1.0;
    w2[s][n]=1.0;


    for(n=0;n<=3000;n++){
        for(s=0;s<=3000;s++){
            for(n=0;n<=3000;n++){
                u2[s+1][n] = (mp*u2[s][n] + delta*(2*mp*u2[s][n]*w2[s+1][n]+a) )/1 + delta*(w2[s+1][n]*w2[s+1][n]+a+1);
                w2[s+1][n] = (mq*w2[s][n] + delta*(mp*u2[s][n]*(mq*w2[s][n]*w2[s][n]+1)+b) )/1 + delta*(w2[s+1][n]*w2[s+1][n]+a+1);
            }
        }
        mp = 0.5*(u2[s][n+1]+ u2[s][n-1]);
        mq = 0.5*(u2[s][n+1]+ u2[s][n-1]);

    for(t = 0.0; t <=3000; t+=dt) {//ルンゲクッタ法で計算
        k0[0][0]=dt*f1(t,u,w);
        k0[1][1]=dt*f2(t,u,w);

        k1[0][0]=dt*f1(t+dt/2.0,u2[s+1][n]+k0[0][0]/2.0,w2[s+1][n]+k0[1][1]/2.0);
        k1[1][1]=dt*f1(t+dt/2.0,u2[s+1][n]+k0[0][0]/2.0,w2[s+1][n]+k0[1][1]/2.0);

        k2[0][0]=dt*f1(t+dt/2.0,u2[s+1][n]+k1[0][0]/2.0,w2[s+1][n]+k1[1][1]/2.0);
        k2[1][1]=dt*f1(t+dt/2.0,u2[s+1][n]+k1[0][0]/2.0,w2[s+1][n]+k1[1][1]/2.0);

        k3[0][0]=dt*f1(t+dt,u2[s+1][n]+k2[0][0],w2[s+1][n]+k2[1][1]);
        k3[1][1]=dt*f1(t+dt,u2[s+1][n]+k2[0][0],w2[s+1][n]+k2[1][1]);

        u2[s+1][n] = u2[s][n] + (k0[0][0]+ k1[0][0]*2 + k2[0][0]*2 + k3[0][0])/6.0;
        w2[s+1][n] = w2[s][n] + (k0[1][1]+ k1[1][1]*2 + k2[1][1]*2 + k3[1][1])/6.0;

        fprintf(output,"%lf, %lf, %lf\n", u2[s+1][n] , w2[s+1][n], t);
        printf("%lf , %lf , %lf\n",u2[s+1][n] , w2[s+1][n], t);
        }
      }
    fclose(output);
    return 0;
}


double f1(double t,double u,double w){
    int n,s;
    double r[3000][3000];
    double a=0.04;
    double u2[3000][3000];
    double w2[3000][3000];
    r[s+1][n] = -u2[s+1][n]*w2[s+1][n]*w2[s+1][n]+a*(1-u2[s+1][n]);
    return 0;
}

double f2(double t,double u,double w){
    int n,s;
    double r[3000][3000];
    double b=0.11;
    double u2[3000][3000];
    double w2[3000][3000];
    r[s+1][n] = u2[s+1][n]*w2[s+1][n]*w2[s+1][n] - b*w2[s+1][n];
    return 0;
}

 発生している問題・エラーメッセージ

gccは通るのですが、プログラムを実行すると強制終了してしまいます。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

checkベストアンサー

+1

突っ込みどころはたくさんありますね。
ざっと気づいたところ。

    u2[s][n]=1.0;
    w2[s][n]=1.0;


snを初期化していないので、どこが初期化されるかわかりません。

    for(n=0;n<=3000;n++){
        for(s=0;s<=3000;s++){
            for(n=0;n<=3000;n++){


nのループが2回入れ子になってる。
ループ回数が0~3000になってる。
配列の要素は0~2999です。

        for(s=0;s<=3000;s++){
            for(n=0;n<=3000;n++){
                u2[s+1][n] = (mp*u2[s][n] + delta*(2*mp*u2[s][n]*w2[s+1][n]+a) )/1 + delta*(w2[s+1][n]*w2[s+1][n]+a+1);
                w2[s+1][n] = (mq*w2[s][n] + delta*(mp*u2[s][n]*(mq*w2[s][n]*w2[s][n]+1)+b) )/1 + delta*(w2[s+1][n]*w2[s+1][n]+a+1);
            }


u2[s+1][n]では、最大でu2[3001][3000]を参照することになり、確保していない領域を参照することになります。

    double k0[2][2], k1[2][2], k2[2][2], k3[2][2];//計算した値を入れる配列

コード内で使ってる要素は[0][0][1][1]なので、二次元配列にする意味がない。

コード全体を通して、[3000][3000]の配列。

初期化せずに使っている。
またサイズが大きすぎてスタックオーバーしているはず。
グローバル変数にするかstatic変数にしてください。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/07/10 13:23

    細かいところまでご指摘ありがとうございました。何とか修正できましたのでベストアンサーにさせていただきます。

    キャンセル

+1

まず問題になりそうなのはここですかね。

int main(void) {
  FILE *output;
  output = fopen("output.dat","w");

  double t = 0.0;
  double dt = 0.01;
  double delta = 0.1;
  double r[3000][3000];
  double u = 1.0, w = 1.0;//初期値
  double a=0.03, b=0.10;//論文での値
  double k0[2][2], k1[2][2], k2[2][2], k3[2][2];//計算した値を入れる配列

  //離散化を構成する
  int i;
  int n,s,p;//mpとmqの添え字
  double mp,mq;
  double u2[3000][3000];
  double w2[3000][3000];
  //double u2[0][0]=0.0;//初期化
  //double w2[0][0]=0.0;//初期化
  u2[s][n]=1.0; // ①
  w2[s][n]=1.0;

  for(n=0;n<=3000;n++){
    for(s=0;s<=3000;s++){
      for(n=0;n<=3000;n++){ // ②


まず①ですが、u2[s][n] にアクセスしようとしていますが、s, n が 初期化されていません
デバッガを介した場合は 0 クリアされていることがありますが、デバッガを介さないと s, n に何が入っているか分かったものではありませんから、変な場所にアクセスして segmentation fault で落ちますな。

そして②ですが、一番大きいループで n を回しているのに、その中でまた n を回すって、何がやりたいんですか?

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+1

関数内で3000x3000なdoubleの配列が3つも宣言されてますのでスタックオーバーフロー起こしてたりしませんか?
3000x3000って900万になりますけどスタック領域そんなに無いですよね?
mallocで確保するとかしなくて大丈夫です?

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.52%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • C

    3670questions

    C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

  • Windows 7

    370questions

    Microsoft Windows 7は過去にリリースされたMicrosoft WindowsのOSであり、Windows8の1代前です。2009年の7月にリリースされ販売されました。Windows7の前はWindowsVistaで、その更に3年前にリリースされました。