C言語で半角スペースをデリミタとしたデータファイルを読み込むプログラムを作っています. まず, データのレコード数とフィールドの数をカウントしてその後, double型の2次元配列に必要なメモリ領域をmalloc関数にて確保して, 2次元配列にデータを代入していくという処理をやらせています.
とうプログラムをコンパイルして実行した所以下のようなエラーが出てどうやらFreeを2重にしてしまっていることがエラーログから分かるのですが, どこを修正していいかわかりません. どなたかお力を貸していただけないでしょうか?
■ソース■
#include<stdio.h>
#include<string.h>
#include<malloc.h>
#define LINE_MAX_SIZE 5120
int main(void){
__road("test.dat");
}
int road(char fname[100]){
__FILE *fp;
__char line[LINE_MAX_SIZE];
__char *tp;
__char *token=" ";
__int rn=0;
__int fn;
__int i=0;
__int j=0;
__
__fp=fopen(fname,"r");
____/*
____ check record number and field number
____*/
____while(fgets(line,sizeof(line),fp)){
______
______tp=strtok(line,token);
______fn=0;
______while(tp!=NULL){
________tp=strtok(NULL,token);
________fn++;
______}
______rn++;
____}
____//printf("rn=%d fn=%d\n",rn,fn);
____/*
______make 2 dimension array dynamically
____*/
______double **data;
______
______data=malloc(sizeof(double *)*rn);
______// then data have 2 pointer to double type
______for(j=0;j<fn;j++){
________data[j]=malloc(sizeof(double)*fn);
______}
____
____/*
____ insert data to array
____*/
____i=j=0;
____while(fgets(line,sizeof(line),fp)){
______j=0;
______tp=strtok(line,token);
______data[i][j]=atof(tp);
______while(tp!=NULL){
________j++;
________tp=strtok(NULL,token);
________data[i][j]=atof(tp);
______}
______i++;
____}
____for(i=0;i<rn;i++){
______for(j=0;j<fn;j++){
________printf("%f ",data[i][j]);
______}
______printf("\n");
____}
____/*
____/ free memory for data[][]
____*/
____if(data){
______for(j=0;j<fn;j++){
________if(data[j]){
__________free(data[j]);
________}
______}
______free(data);
____}
__fclose(fp);
}
/*
int freeMem(){
}
*/
No.5ベストアンサー
- 回答日時:
for(j=0;j<fn;j++){
とその上の malloc とを比較してください.
そうそう, エラーメッセージは「Freeを2重にしてしまっている」とは言ってないよね.
この回答への補足
>data=malloc(sizeof(double *)*rn);
でrn個のポインタのためのメモリ領域を確保しているにもかかわらず
forでfn個まわしてしまったいるのですね…
正しくは
for(j=0;j<rn;j++){
ですね.
さっそく修正してコンパイル実行した所. 以下のような結果になり値が正しく表示されませんでした.
■結果■
0.000000 0.000000 0.000000 0.000000
0.000000 0.000000 0.000000 0.000000
0.000000 0.000000 0.000000 0.000000
Segmentation fault
No.6
- 回答日時:
間違えて
for(j=0;j<fn;j++){
ってなってるところ, 実は 2か所あったのね.... かと思うとこれで正しいところもあったりするし, 少なくとも i と j については役割分担がうまくいってない.
あとは #3 の話. 最初の while でファイルを全部読んじゃってるから, 2つ目の while の前でファイルポインタを戻さないといけない.
この回答への補足
>i と j については役割分担がうまくいってない.
iは行をjはフィールド方向という風に整理してみました.
>while でファイルを全部読んじゃってるから, 2つ目の while の前でファイルポインタを戻さないといけない.
確かにそうですね…fseekでファイルポインタ戻さないといけないです.
■修正後■
#include<stdio.h>
#include<string.h>
#include<malloc.h>
#include<stdlib.h>
#define LINE_MAX_SIZE 5120
int main(void){
_road("test.dat");
}
int road(char fname[100]){
_FILE *fp;
_char line[LINE_MAX_SIZE];
_char *tp;
_char *token=" ";
_int rn=0;
_int fn;
_int i=0;
_int j=0;
_
_fp=fopen(fname,"r");
_if(fp==NULL){
__fprintf(stderr,"%s : No such file or directory!!\n",fname);
_}
__/*
__ check record number and field number
__*/
__while(fgets(line,sizeof(line),fp)){
___
___tp=strtok(line,token);
___fn=0;
___while(tp!=NULL){
____tp=strtok(NULL,token);
____fn++;
___}
___rn++;
__}
__//printf("rn=%d fn=%d\n",rn,fn);
__/*
___make 2 dimension array dynamically
__*/
___double **data;
___
___data=malloc(sizeof(double *)*rn);
___if(data==NULL){
____fprintf(stderr,"Failed fetch memory\n");
____exit(1);
___}
___// then data have 2 pointer to double type
___for(i=0;i<rn;i++){
____data[i]=malloc(sizeof(double)*fn);
____if(data[i]==NULL){
_____fprintf(stderr,"Failed fetch memory\n");
_____exit(1);
____}
___}
__
__/*
__ insert data to array
__*/
__// move file pointer to file haed
__fseek(fp,0L,SEEK_SET);
__i=j=0;
__while(fgets(line,sizeof(line),fp)){
___j=0;
___tp=strtok(line,token);
___data[i][j]=atof(tp);
___while(tp!=NULL){
____j++;
____tp=strtok(NULL,token);
____data[i][j]=atof(tp);
___}
___i++;
__}
__for(i=0;i<rn;i++){
___for(j=0;j<fn;j++){
____printf("%f ",data[i][j]);
___}
___printf("\n");
__}
__/*
__/ free memory for data[][]
__*/
__if(data){
___for(i=0;i<rn;i++){
____if(data[i]){
_____free(data[i]);
____}
___}
___free(data);
__}
_fclose(fp);
}
/*
int freeMem(){
}
*/
No.4
- 回答日時:
あと, 直接問題にはならないこともあるけど突っ込みどころ:
・fopen や malloc の返り値はちゃんと確認すべし
・英語がいろいろと怪しい
・関数の引数に配列を指定した意図はなんだろう
この回答への補足
>fopen や malloc の返り値はちゃんと確認すべし
分りました.
if(malloc(****)==NULL){
______printf("malloc failed!!\n");
______exit(1);
}
のようにしときます.
>英語がいろいろと怪しい
すみません. . .
>関数の引数に配列を指定した意図はなんだろう
特に深い意図はありません.
ファイル名を関数に渡したかっただけです.
No.1
- 回答日時:
>以下のようなエラー
どこにありますか?
また、差し支えがない範囲で、入力データの現物を見せていただくことは可能ですか?
この回答への補足
エラーは, 字数の関係で掲載できませんでした. すみませんでした. データファイルは, 以下のようになっています. なお, 私のPC環境は, ubuntu10.04でadm64. コンパイラはgcc(4.4.3)です.
■データファイル■
12.03 3.25 3.59 2.03
5.36 4.52 0.23 3.40
4.69 8.69 1.23 5.40
■エラー■
0.000000 0.000000 0.000000 0.000000
0.000000 0.000000 0.000000 0.000000
0.000000 0.000000 0.000000 0.000000
*** glibc detected *** ./a.out: double free or corruption (out): 0x000000000130b270 ***
======= Backtrace: =========
/lib/libc.so.6(+0x775b6)[0x7f8b00c7a5b6]
/lib/libc.so.6(cfree+0x73)[0x7f8b00c80e53]
./a.out[0x400b57]
./a.out[0x400807]
/lib/libc.so.6(__libc_start_main+0xfd)[0x7f8b00c21c4d]
./a.out[0x400739]
======= Memory map: ========
00400000-00401000 r-xp 00000000 08:01 7210411 /home/hoge/prog/roadData_c/a.out
00600000-00601000 r--p 00000000 08:01 7210411 /home/hoge/prog/roadData_c/a.out
00601000-00602000 rw-p 00001000 08:01 7210411 /home/hoge/prog/roadData_c/a.out
0130b000-0132c000 rw-p 00000000 00:00 0 [heap]
7f8afc000000-7f8afc021000 rw-p 00000000 00:00 0
7f8afc021000-7f8b00000000 ---p 00000000 00:00 0
7f8b009ec000-7f8b00a02000 r-xp 00000000 08:01 9437263 /lib/libgcc_s.so.1
7f8b00a02000-7f8b00c01000 ---p 00016000 08:01 9437263 /lib/libgcc_s.so.1
7f8b00c01000-7f8b00c02000 r--p 00015000 08:01 9437263 /lib/libgcc_s.so.1
7f8b00c02000-7f8b00c03000 rw-p 00016000 08:01 9437263 /lib/libgcc_s.so.1
7f8b00c03000-7f8b00d7d000 r-xp 00000000 08:01 9437484 /lib/libc-2.11.1.so
7f8b00d7d000-7f8b00f7c000 ---p 0017a000 08:01 9437484 /lib/libc-2.11.1.so
7f8b00f7c000-7f8b00f80000 r--p 00179000 08:01 9437484 /lib/libc-2.11.1.so
7f8b00f80000-7f8b00f81000 rw-p 0017d000 08:01 9437484 /lib/libc-2.11.1.so
7f8b00f81000-7f8b00f86000 rw-p 00000000 00:00 0
7f8b00f86000-7f8b00fa6000 r-xp 00000000 08:01 9437267 /lib
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・14歳の自分に衝撃の事実を告げてください
- ・架空の映画のネタバレレビュー
- ・「お昼の放送」の思い出
- ・昨日見た夢を教えて下さい
- ・ちょっと先の未来クイズ第4問
- ・【大喜利】【投稿~10/21(月)】買ったばかりの自転車を分解してひと言
- ・メモのコツを教えてください!
- ・CDの保有枚数を教えてください
- ・ホテルを選ぶとき、これだけは譲れない条件TOP3は?
- ・家・車以外で、人生で一番奮発した買い物
- ・人生最悪の忘れ物
- ・【コナン30周年】嘘でしょ!?と思った○○周年を教えて【ハルヒ20周年】
- ・ハマっている「お菓子」を教えて!
- ・最近、いつ泣きましたか?
- ・夏が終わったと感じる瞬間って、どんな時?
- ・10秒目をつむったら…
- ・人生のプチ美学を教えてください!!
- ・あなたの習慣について教えてください!!
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・都道府県穴埋めゲーム
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
fscanfでループしてしまう。
-
ファイルが読み込めない・・・
-
bmpファイルの解析
-
日本語ファイル名のFTPについて
-
二分探索木への挿入
-
数値のみ抽出(C言語)
-
複数ファイルの同時読み込みの...
-
C言語でクロマキー合成をする方法
-
信頼区間の1.96や1.65ってどこ...
-
Enterキーを押されたら次の処理...
-
2÷3などの余りについて
-
プログラミング初心者です。 Py...
-
C言語を実行すると-infが出てき...
-
プログラムでの数字につく”f”の...
-
マイナスからプラスへ転じた時...
-
C言語での引数の省略方法
-
プログラミングで二番目に大き...
-
分数の足し算をさせるプログラ...
-
if と配列の組み合わせ
-
数字以外が入力されたらエラー...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
fopenでファイル名に、変数を使...
-
C言語でファイル読み書きを早く...
-
c言語でのfscanfについて
-
ファイル出力で改行を入れたい!
-
複数ファイルの同時読み込みの...
-
日本語ファイル名のFTPについて
-
エラーがわかりません、、
-
CRC32の計算方法
-
ファイルへの書込み処理が異常...
-
C言語でセグメンテーションエ...
-
fread()エラー
-
C言語 連番データの読み込み
-
C言語でクロマキー合成をする方法
-
C言語にてXMLファイルから任意...
-
画像の白黒表示
-
fgets( ) の返り値は何?
-
C言語 csv 配列
-
エラー C2664
-
ガンマ変換 C言語でプログラ...
-
a*(1-exp(-bx))+cの近似の方法
おすすめ情報