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

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
water

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

#1

投稿記事 by water » 9ヶ月前

ファイルから値を読み込むプログラムを作ったが、テキストファイルをすべて読んだ後に「...exeは動作を停止しました」と表示される。私の予想ではポインタ配列の部分がどこか間違っていると思ったのですが、どなたか分かる方がいたらご教授ください。よろしくお願いします。

コード:

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

water

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

#2

投稿記事 by water » 9ヶ月前

[追記]すいません。読み込みファイルは下の通りです。

コード:

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

アバター
みけCAT
記事: 6013
登録日時: 7年前
住所: 千葉県
連絡を取る:

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

#3

投稿記事 by みけCAT » 9ヶ月前

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

water

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

#4

投稿記事 by water » 9ヶ月前

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

Math

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

#5

投稿記事 by Math » 9ヶ月前

コード:

#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;
}
として実行した結果は

コード:

        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
続行するには何かキーを押してください . . .

アバター
みけCAT
記事: 6013
登録日時: 7年前
住所: 千葉県
連絡を取る:

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

#6

投稿記事 by みけCAT » 9ヶ月前

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

返信

“C言語何でも質問掲示板” へ戻る