合計 昨日 今日

ファイルからの値読み込みプログラムに関して

フォーラムルール
フォーラムルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
Name: water
[URL]
Date: 2017年9月13日(水) 22:36
No: 1
(OFFLINE)

 ファイルからの値読み込みプログラムに関して

ファイルから値を読み込むプログラムを作ったが、テキストファイルをすべて読んだ後に「...exeは動作を停止しました」と表示される。私の予想ではポインタ配列の部分がどこか間違っていると思ったのですが、どなたか分かる方がいたらご教授ください。よろしくお願いします。
コード[C++]: 全て選択
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
 
int main(){
 
int m;          //メッシュ番号
int i;          //計算時の時間変数 0<=i<=3
int me;         //最終水位点(最後のメッシュ番号)
int mes;        //最終流速点(me-1)
int jend;       //最終計算ステップ数
int jout;       //出力ステップ間隔
int *isel;      //出力メッシュ番号
int inout;      //出力メッシュ数
int nn1;        //水位境界点における変化点の数
int nn2;        //流量境界点における変化点の数
int *jwl;       //下流境界条件の変化点のステップ
int *jqin;      //上流境界条件の変化点のステップ
 
 
double **hv;    //水深と流速を示す配列
double dx;      //距離刻み幅
double dt;      //時間刻み幅
double rn;      //マニングの粗度係数
double syokih;  //初期水深
double sb;      //水路底面
double *wlb;    //下流水位境界条件の変化点水深
double *qin;    //上流流量境界条件の変化点流量
double qinn;    //流量境界値
double hm;      //水深境界値
double *aw;     //m=遇→メッシュ番号mの流水断面積、m=奇→メッシュ番号m+1の水面幅
double *q;      //メッシュ番号mの通過流量*mは奇数
double qe;      //横流入量(流入のときは負、流出のときは正
 
 
 
  FILE *FP;
 
  FP=fopen("input2.txt","r");
 
/////////////////データの読み込み(配列以外)/////////////////////
 
  fscanf(FP,"%d %d\n",&me, &mes);
  printf("%10d%10d\n",me, mes);
  fscanf(FP,"%d %d %d %d %d\n",&jout, &jend, &inout, &nn1, &nn2);
  printf("%10d%10d%10d%10d%10d\n",jout, jend, inout, nn1, nn2);
  fscanf(FP,"%lf %lf %lf %lf %lf\n",&dx, &dt, &rn, &sb, &syokih);
  printf("%10.3f%10.3f%10.3f%10.3f%10.3f\n",dx, dt, rn, sb, syokih);
 
//////////////////////////配列の確保////////////////////////////
 
  isel =(int *)malloc(sizeof(int)*(inout+1));
  jwl  =(int *)malloc(sizeof(int)*(nn1+1));
  jqin =(int *)malloc(sizeof(int)*(nn2+1));
  wlb  =(double *)malloc(sizeof(double)*(nn1+1));
  qin  =(double *)malloc(sizeof(double)*(nn2+1));
  aw   =(double *)malloc(sizeof(double)*(me+1));
  q    =(double *)malloc(sizeof(double)*(mes+1));
  hv=(double **)malloc(sizeof(double *)*(me+1));
 
  for(m=0;m<me+1;m++){
    hv[m]=(double *)malloc(sizeof(double)*(5));
  }
 
  for(m=0;m<me+1;m++){
    free(hv[m]);
  }
 
  free(hv);
  free(q);
  free(aw);
  free(qin);
  free(wlb);
  free(jqin);
  free(jwl);
  free(isel);
 
/////////////////データの読み込み(配列)///////////////////////
 
  for(m=1; m<me+1; m+=2){
    fscanf(FP,"%lf",&hv[m][1]);
    printf("%10.3f\n",hv[m][1]);
  }
//  exit(0);
 
  for(m=0; m<me; m+=2){
    fscanf(FP,"%lf",&hv[m][2]);
    printf("%10.3f\n",hv[m][2]);
  }
 
 
  for(m=0; m<inout; m++){
    fscanf(FP,"%d",&isel[m]);
    printf("%10d\n",isel[m]);
  }
 
  for(i=0; i<nn1; i++){
    fscanf(FP,"%d %lf",&jwl[i],&wlb[i]);
    printf("%10d%10.3f\n",jwl[i],wlb[i]);
  }
 
  for(i=0; i<nn2; i++){
    fscanf(FP,"%d %lf",&jqin[i],&qin[i]);
    printf("%10d%10.3f\n",jqin[i],qin[i]);
  }
 
 
  fclose(FP);
  return 0;
}

Name: water
[URL]
Date: 2017年9月13日(水) 23:00
No: 2
(OFFLINE)

 Re: ファイルからの値読み込みプログラムに関して

[追記]すいません。読み込みファイルは下の通りです。
コード[C++]: 全て選択
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
12 11
2 2402 6 2 4
400.000 30.000 0.025 10.000 4.000
0.000
0.400
0.800
1.200
1.600
2.000
10.000
10.000
10.000
10.000
10.000
10.000
1
3
5
7
9
11
2 4.000
2402 4.000
2 30.000
1202 30.000
1322 60.000
2402 60.000

Name: みけCAT
[URL]
伝説なるハッカー(680,600 ポイント)
Date: 2017年9月13日(水) 23:11
No: 3
(ONLINE)

 Re: ファイルからの値読み込みプログラムに関して

freeに渡したポインタをデリファレンス(配列の添字を使ったアクセスを含む)してはいけません。dangling pointerというバグで、未定義動作になります。
どうしてせっかく確保した配列をすぐに捨ててしまうのですか?
とりあえず、freeの呼び出しを全て削除してください。 (メモリはどうせプログラムが終了したらOSが回収してくれるはずなので、freeを使わなくても小規模なら問題ありません)
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

Name: water
[URL]
Date: 2017年9月13日(水) 23:22
No: 4
(OFFLINE)

 Re: ファイルからの値読み込みプログラムに関して

無事、動作しました。ありがとうございました。
freeの機能について理解できていませんでした。

Name: Math
[URL]
Date: 2017年9月13日(水) 23:25
No: 5
(OFFLINE)

 Re: ファイルからの値読み込みプログラムに関して

コード[C++]: 全て選択
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
 
int main() {
 
    int m;          //メッシュ番号
    int i;          //計算時の時間変数 0<=i<=3
    int me;         //最終水位点(最後のメッシュ番号)
    int mes;        //最終流速点(me-1)
    int jend;       //最終計算ステップ数
    int jout;       //出力ステップ間隔
    int *isel;      //出力メッシュ番号
    int inout;      //出力メッシュ数
    int nn1;        //水位境界点における変化点の数
    int nn2;        //流量境界点における変化点の数
    int *jwl;       //下流境界条件の変化点のステップ
    int *jqin;      //上流境界条件の変化点のステップ
 
 
    double **hv;    //水深と流速を示す配列
    double dx;      //距離刻み幅
    double dt;      //時間刻み幅
    double rn;      //マニングの粗度係数
    double syokih;  //初期水深
    double sb;      //水路底面
    double *wlb;    //下流水位境界条件の変化点水深
    double *qin;    //上流流量境界条件の変化点流量
    double qinn;    //流量境界値
    double hm;      //水深境界値
    double *aw;     //m=遇→メッシュ番号mの流水断面積、m=奇→メッシュ番号m+1の水面幅
    double *q;      //メッシュ番号mの通過流量*mは奇数
    double qe;      //横流入量(流入のときは負、流出のときは正
 
 
 
    FILE *FP;
 
    FP = fopen("input2.txt", "r");
 
    /////////////////データの読み込み(配列以外)/////////////////////
 
    fscanf(FP, "%d %d\n", &me, &mes);
    printf("%10d%10d\n", me, mes);
    fscanf(FP, "%d %d %d %d %d\n", &jout, &jend, &inout, &nn1, &nn2);
    printf("%10d%10d%10d%10d%10d\n", jout, jend, inout, nn1, nn2);
    fscanf(FP, "%lf %lf %lf %lf %lf\n", &dx, &dt, &rn, &sb, &syokih);
    printf("%10.3f%10.3f%10.3f%10.3f%10.3f\n", dx, dt, rn, sb, syokih);
 
    //////////////////////////配列の確保////////////////////////////
 
    isel = (int *)malloc(sizeof(int)*(inout + 1));
    jwl = (int *)malloc(sizeof(int)*(nn1 + 1));
    jqin = (int *)malloc(sizeof(int)*(nn2 + 1));
    wlb = (double *)malloc(sizeof(double)*(nn1 + 1));
    qin = (double *)malloc(sizeof(double)*(nn2 + 1));
    aw = (double *)malloc(sizeof(double)*(me + 1));
    q = (double *)malloc(sizeof(double)*(mes + 1));
    hv = (double **)malloc(sizeof(double *)*(me + 1));
 
    for (m = 0;m<me + 1;m++) {
        hv[m] = (double *)malloc(sizeof(double)*(5));
    }
 
    for (m = 0;m<me + 1;m++) {
        free(hv[m]);
    }
 
   
 
    /////////////////データの読み込み(配列)///////////////////////
 
    for (m = 1; m<me + 1; m += 2) {
        fscanf(FP, "%lf", &hv[m][1]);
        printf("%10.3f\n", hv[m][1]);
    }
    //  exit(0);
 
    for (m = 0; m<me; m += 2) {
        fscanf(FP, "%lf", &hv[m][2]);
        printf("%10.3f\n", hv[m][2]);
    }
 
 
    for (m = 0; m<inout; m++) {
        fscanf(FP, "%d", &isel[m]);
        printf("%10d\n", isel[m]);
    }
 
    for (i = 0; i<nn1; i++) {
        fscanf(FP, "%d %lf", &jwl[i], &wlb[i]);
        printf("%10d%10.3f\n", jwl[i], wlb[i]);
    }
 
    for (i = 0; i<nn2; i++) {
        fscanf(FP, "%d %lf", &jqin[i], &qin[i]);
        printf("%10d%10.3f\n", jqin[i], qin[i]);
    }
 
 
    fclose(FP);
 
    free(hv);
    free(q);
    free(aw);
    free(qin);
    free(wlb);
    free(jqin);
    free(jwl);
    free(isel);
    return 0;
}

として実行した結果は
コード[C++]: 全て選択
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
        12        11
         2      2402         6         2         4
   400.000    30.000     0.025    10.000     4.000
     0.000
     0.400
     0.800
     1.200
     1.600
     2.000
    10.000
    10.000
    10.000
    10.000
    10.000
    10.000
         1
         3
         5
         7
         9
        11
         2     4.000
      2402     4.000
         2    30.000
      1202    30.000
      1322    60.000
      2402    60.000
続行するには何かキーを押してください . . .

Name: みけCAT
[URL]
伝説なるハッカー(680,600 ポイント)
Date: 2017年9月13日(水) 23:59
No: 6
(ONLINE)

 Re: ファイルからの値読み込みプログラムに関して

MathさんのNo: 5のプログラムも、freeに渡した後のポインタが指す領域を読み書きしており、未定義動作ですね。
運悪く不都合が現れなかったのですね。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)


Return to C言語何でも質問掲示板

オンラインデータ

このフォーラムを閲覧中のユーザー: ターボ & ゲスト[20人]