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

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

トピックに返信する


答えを正確にご入力ください。答えられるかどうかでスパムボットか否かを判定します。

BBCode: ON
[img]: ON
[flash]: OFF
[url]: ON
スマイリー: OFF

トピックのレビュー
   

展開ビュー トピックのレビュー: ファイルからの値読み込みプログラムに関して

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

#6

by みけCAT » 6年前

MathさんのNo: 5のプログラムも、freeに渡した後のポインタが指す領域を読み書きしており、未定義動作ですね。
運悪く不都合が現れなかったのですね。

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

#5

by Math » 6年前

コード:

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

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

#4

by water » 6年前

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

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

#3

by みけCAT » 6年前

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

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

#2

by water » 6年前

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

コード:

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

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

#1

by water » 6年前

ファイルから値を読み込むプログラムを作ったが、テキストファイルをすべて読んだ後に「...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;
}

ページトップ