C言語でのファイル読み込みで、ファイルを開いてデータを読み込んで表示することはできたのですが、最後のfclose(fp)でセグメンテーション違反になります。一番最後のwhileループをコメントアウトしたところセグメンテーション違反にはならなかったので、ここに何か問題があると思うのですが、どこが悪いのかが分かりません...
#include<stdio.h>
#include<stdlib.h>
main(void){
FILE *fp;
int i=0 , j=0 ,cnt = 0 , c=0;
char *name="data.txt";
float *buf1,*buf2;
if((fp = fopen(name,"r")) == NULL){
printf("error\n");
return 0;
}
else{
while((c = getc(fp)) != EOF) {
if(c == '\n') cnt++;
}
printf(">>%d<<\n",cnt+1);
rewind(fp);
buf1 = (float *)malloc( (int)(cnt/2) +1);
buf2 = (float *)malloc( (int)(cnt/2) +1);
/*ここからがおかしい?*/
while(1){
if( fscanf( fp ,"%f %f",&buf1[i],&buf2[i])==EOF )break;
printf("%f %f\n",buf1[i],buf2[i]);
i++;
}
fclose(fp);
}
return 0;
}
なぜセグメンテーション違反になっているのでしょうか?
No.2ベストアンサー
- 回答日時:
数値が1行に一つ、2行で1セットなら、データ数+番兵用に一つで、 「行数/2 + 1」個、というのは間違いではないでしょう。
※ 1行に2つデータが並んでいる、とかになると、上記計算では間違いです。
問題は、mallocの引数に指定する値は、「データの個数」ではなく、「領域の大きさ」だということ。
配列として使いたいなら、 「1要素の大きさ」×「要素数」以上を指定しないと領域不足になる、ということです。
floatの配列を n/2+1用意したいなら、 sizeof(float)*(n/2+1)です。
エラーで止まるところ≠問題のあるところ、なのが、プログラミングの難しいところ。
ただ、セグメンテーション違反が出るときは、9割方は配列、ポインタ絡みです。
配列の添字が範囲外、確保してないアドレスやNULLへのアクセス、等
回答有難うございました。
その通り、malloc部分を修正するとセグメンテーション違反にならなくなりました。
「1要素の大きさ」×「要素数」を指定しなければならないというのも、以前に読んだ本の中にしっかり書かれていたのに、完璧に忘れてしまっていましたorz
データは"一行に二つ"ですので、別の回答者のasuncionさんがおっしゃっているように
buf1 = (float *)malloc( sizeof(float)*(cnt +1));
と修正た結果、正しく動作しました。
ありがとうございました・
No.3
- 回答日時:
mallocの引数に sizeof(float) *
が抜けているというご指摘は#2さんのおっしゃるとおりですね。
ただ、
>数値が1行に一つ、2行で1セットなら、データ数+番兵用に一つで、
> 「行数/2 + 1」個、というのは間違いではないでしょう。
10行(20個)分のデータを読みたいのに
sizeof(float) * 6
で本当にいいのかどうかは疑問が残ります。
この回答への補足
おそらくkmeeさんが
>数値が1行に一つ、2行で1セットなら、データ数+番兵用に一つで、
> 「行数/2 + 1」個、というのは間違いではないでしょう。
とおっしゃっているのは、
「一行に一つのデータで10行分のデータがあり(全データ数が10個)、それを二行ずつ1セットにして読み込む場合」
ではないかと思います。なのでそれぞれの配列の要素数は5個となり、sizeof(float)*6で大丈夫では無いかと思います。
自分の質問の場合は、asuncionさんのおっしゃっている通りなので間違っていました。
No.1
- 回答日時:
変数cntは、ファイルの行数であるとお見受けしました。
違っていたらおっしゃってください。
さて、
>buf1 = (float *)malloc( (int)(cnt/2) +1);
>buf2 = (float *)malloc( (int)(cnt/2) +1);
malloc関数の引数をこのようにされた理由は何でしょうか。
ファイルの行数分だけ確保する必要はないのでしょうか。
この回答への補足
回答ありがとうございます。
確かに変な記述してますね…気付きませんでした。
以前に作ったものを参考にしながら書いたので、前後との整合性を考えずそのままにしてしまっていました。
ご指摘の通り、cntはファイルの行数を数えるためのものです。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- C言語・C++・C# このプログラミング誰か教えてくれませんか 1 2022/06/02 15:27
- C言語・C++・C# バイナリファイルをコピーするのにかかる時間を測りたいのですが実行するとFatel error:gli 2 2022/11/03 01:10
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- C言語・C++・C# C言語のエラーについて 2 2022/07/11 13:56
- C言語・C++・C# プログラミング c言語 4 2023/03/07 01:05
- C言語・C++・C# c言語でユーザ関数を利用して入力された文字列を反転させるプログラムを作りたいです。 3 2023/01/29 19:47
- C言語・C++・C# C言語 プログラミング 4 2022/05/22 11:53
- C言語・C++・C# C言語で再起関数とポインタを用いて文字列反転をする方法がわかりません。 4 2023/04/29 20:32
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
関数から配列を返すには?
-
配列の要素数に変数を入れたい...
-
C言語の2次元配列 容量が大き...
-
C#で構造体の配列を持った構造...
-
5人分の氏名と英語、国語、数...
-
Cのエラー
-
c言語のポインタへの文字列入力...
-
C言語 配列の長さの上限
-
init関数の意味
-
long型のデータをバイト型の配...
-
fopne で失敗する原因
-
ファイル名「1.jpg ~10.jpg~...
-
Integer変数をカラにしたいので...
-
セグメントエラー
-
C言語でポインターで詰まってい...
-
市販のビンゴカードについて
-
Linked List(線形リスト)を使...
-
nullと""、\\0とEOFの違いにつ...
-
配列で格納したものをmsgboxで...
-
ヒープメモリの解放について
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
関数から配列を返すには?
-
配列の要素数に変数を入れたい...
-
c言語
-
構造体のextern方法
-
define で 配列
-
C#で構造体の配列を持った構造...
-
C言語において、 配列要素をひ...
-
コンボボックスでデフォルト値...
-
2番目の最大値を求める
-
C言語の2次元配列 容量が大き...
-
C#で配列が空かを判定するには?
-
MFCのCArrayを使った二次元配列
-
C言語の課題が出たのですが自力...
-
C言語 ファイルの指定された行...
-
Cのエラー
-
ポインタを使って構造体の配列...
-
配列のアドレス部
-
char型配列をint型に代入するには
-
MFC - ダイアログボックスのPic...
-
C言語から質問です。
おすすめ情報