• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:fclose()でセグメンテーション違反)

fclose()でセグメンテーション違反

このQ&Aのポイント
  • C言語でのファイル読み込みで、ファイルを開いてデータを読み込んで表示することはできたが、fclose()でセグメンテーション違反になる。
  • whileループをコメントアウトするとセグメンテーション違反が発生しないため、問題箇所を特定したい。
  • セグメンテーション違反が発生する原因を調査し、修正方法を知りたい。

質問者が選んだベストアンサー

  • ベストアンサー
  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.2

数値が1行に一つ、2行で1セットなら、データ数+番兵用に一つで、 「行数/2 + 1」個、というのは間違いではないでしょう。 ※ 1行に2つデータが並んでいる、とかになると、上記計算では間違いです。 問題は、mallocの引数に指定する値は、「データの個数」ではなく、「領域の大きさ」だということ。 配列として使いたいなら、 「1要素の大きさ」×「要素数」以上を指定しないと領域不足になる、ということです。 floatの配列を n/2+1用意したいなら、 sizeof(float)*(n/2+1)です。 エラーで止まるところ≠問題のあるところ、なのが、プログラミングの難しいところ。 ただ、セグメンテーション違反が出るときは、9割方は配列、ポインタ絡みです。 配列の添字が範囲外、確保してないアドレスやNULLへのアクセス、等

U-NAGI
質問者

お礼

回答有難うございました。 その通り、malloc部分を修正するとセグメンテーション違反にならなくなりました。 「1要素の大きさ」×「要素数」を指定しなければならないというのも、以前に読んだ本の中にしっかり書かれていたのに、完璧に忘れてしまっていましたorz データは"一行に二つ"ですので、別の回答者のasuncionさんがおっしゃっているように buf1 = (float *)malloc( sizeof(float)*(cnt +1)); と修正た結果、正しく動作しました。 ありがとうございました・

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (2)

  • asuncion
  • ベストアンサー率33% (2126/6286)
回答No.3

mallocの引数に sizeof(float) * が抜けているというご指摘は#2さんのおっしゃるとおりですね。 ただ、 >数値が1行に一つ、2行で1セットなら、データ数+番兵用に一つで、 > 「行数/2 + 1」個、というのは間違いではないでしょう。 10行(20個)分のデータを読みたいのに sizeof(float) * 6 で本当にいいのかどうかは疑問が残ります。

U-NAGI
質問者

お礼

丁寧な回答、ありがとうございました。エラーのモヤモヤがすっきりしました^^

U-NAGI
質問者

補足

おそらくkmeeさんが >数値が1行に一つ、2行で1セットなら、データ数+番兵用に一つで、 > 「行数/2 + 1」個、というのは間違いではないでしょう。 とおっしゃっているのは、 「一行に一つのデータで10行分のデータがあり(全データ数が10個)、それを二行ずつ1セットにして読み込む場合」 ではないかと思います。なのでそれぞれの配列の要素数は5個となり、sizeof(float)*6で大丈夫では無いかと思います。 自分の質問の場合は、asuncionさんのおっしゃっている通りなので間違っていました。

全文を見る
すると、全ての回答が全文表示されます。
  • asuncion
  • ベストアンサー率33% (2126/6286)
回答No.1

変数cntは、ファイルの行数であるとお見受けしました。 違っていたらおっしゃってください。 さて、 >buf1 = (float *)malloc( (int)(cnt/2) +1); >buf2 = (float *)malloc( (int)(cnt/2) +1); malloc関数の引数をこのようにされた理由は何でしょうか。 ファイルの行数分だけ確保する必要はないのでしょうか。

U-NAGI
質問者

補足

回答ありがとうございます。 確かに変な記述してますね…気付きませんでした。 以前に作ったものを参考にしながら書いたので、前後との整合性を考えずそのままにしてしまっていました。 ご指摘の通り、cntはファイルの行数を数えるためのものです。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • セグメンテーション違反

    約数を表示したいのですが、以下でセグメンテーション違反が発生してしまいます。解説お願いします。 #include<stdio.h> main() { int n, i; scanf("%d",n); for(i=1;i<=n-1;i++){ if(n&i==0){ printf("%d",i); } } }

  • 「セグメンテーション違反」について

    参考書に載っていたプログラムを打ち込みながら勉強していたのですが、次のプログラムを動かしたときに「セグメンテーション違反」と出てきました。 /* 可変書式による印字_簡単な棒グラフ */ #include <stdio.h> main() { char *f, *a; int i; f="%2d = %-20.1s\n"; a="********************"; for(i=1; i<10; i++){ *(f+11)=i+'0'; printf(f,i,a); } } コンパイル後に、 「セグメンテーション違反です」 と、表示されて終わってしまいます。 何処が問題だったのでしょうか???教えて頂ければ幸いです。

  • C言語 セグメンテーション違反

    最大値検索法のプログラムソースを書きましたが、 実行すると、セグメンテーション違反となってしまいます。 どこがおかしいのでしょうか? 分かる方、教えてください。 宜しくお願いします。 swapのソース #include <stdio.h> void swap(int *px,int *py); int main (void) { FILE *fp; if ((fp=fopen("file.txt","rt"))==NULL){ printf("File open error.\n"); //ファイルが無い場合のエラー処理// return 0; } int i,a[10]; for(i=0;i<100;i++){ fscanf(fp,"%d,",&a[i]); //ファイルから読み込み処理。// } fclose(fp); //初期データの並びの表示// for(i=0;i<10;i++) printf("[%d]=%d\n",i,a[i]); /*1.ソートすべきデータの中で最大のデータを見つけ、 2.そのデータを最後のデータと入れ替える。 最大データは配列のどこにあるのか⇒maxi              その値⇒max とする。*/ //データが10個の場合 int max,maxi,j; max=a[0],maxi=0; for(i = 0;i < 9; i++){ if(a[i + 1] > max){ max = a[i + 1]; maxi = i + 1; } swap(&a[maxi],&a[9-j]); for(j=0;j<9;j++){ printf("%d \n",j); printf("i=%d\n ",i); max=a[0], maxi=0; for(i=0;i<9-j;i++){ //最大値をもつデータ探索;(カウンタ変数) max++; //最大データと探索範囲最後のデータとの入れ替え: int n; n=maxi; maxi=max; max=n; printf("maxi=%d \n ",maxi); printf("i=%d\n ",i); printf("j=%d \n",j); } } if((fp=fopen("file.txt","wt"))==NULL){ printf("File open error.\n"); return 0; } for(i=0;i<100;i++){ fprintf(fp,"%d,",a[i]); } fclose(fp); } sortのソース #include<stdio.h> void swap (int *px,int *py); void swap (int *px,int *py) { int n; n =*px; *px = *py; *py = n; }

  • セグメンテーション違反

    OSはリナックスでC言語です。 #include<stdio.h> #include<stdlib.h> typedef struct{ int id; char *name; }user; int main(void) { user *users; int i,j; users=(user *)malloc(sizeof(user)*100); for(j=0;j<5;j++) scanf("%d",&(users+j)->id); scanf("%s",(users+j)->name); free(users); printf("input your id;"); scanf("%d",&i); printf("NO%d %s\n",(users+i)->id,(users+i)->name); return 0; } 上記のプログラムソースでセグメンテーション違反と出てしまいます。 原因はなんなのでしょうか。 教えていただければ光栄です。

  • セグメンテーション違反

    C言語でネットワークを流れるパケットの取得&解析を行っているのですが、実行時にセグメンテーション違反と出てしまい、困っています。デバッグオプションをつけてやってみたところ、プログラムが中断されたところは分かったのですが、どこが悪いのか分かりません。どなたかあやしいところがありましたらお教え下さい。 OSはLinuxでコンパイラはgccです。 void udp_scanport(struct ip *ip, struct udphdr *udp) { static struct in_addr *ipaddr[1024]; static int i = -1; static int udp_count[1024]; struct in_addr *inwk; static u_short udp_port[1024]; int u = 0; int k = 0; i++; inwk = (struct in_addr *)malloc(sizeof(struct in_addr)); memcpy(inwk, &ip->ip_src, sizeof(struct in_addr)); ipaddr[i] = (struct in_addr *)inwk; printf("送信元IPアドレス:%15s\n", inet_ntoa(*(struct in_addr *) ipaddr[i])); udp_port[i] = udp->uh_dport; /*デバッグしたら中断したところ*/ printf("UDP送信先ポート番号:%15u\n", ntohs(udp_port[i])); if (i == 100) free(inwk); }

  • クイックソートプログラムでセグメンテーション違反がでるのですが

    クイックソートのプログラムを作成したのですが、 実行するとセグメンテーション違反が発生して、上手くいきません。何処に原因があるのでしょうか? また、セグメンテーションン違反とはどういったころなのでしょうか? アドバイス宜しくお願いします。 #include <stdio.h> int quick_sort(int *a,int start,int end); int partition(int *a,int start,int end); main() { int n; int a[n]; int i; printf("ソートしたい要素の個数は?\n"); scanf("%d",&n); for(i=0;i<=n-1;i++) a[i]=0; for(i=0;i<=n-1;i++){ printf("%dのデータを入力してください。\n",i+1); scanf("%d",&a[i]); } printf("ソート前のデータは以下の通り\n"); for(i=0;i<=n-1;i++) printf("%d ",a[i]); quick_sort(*a,1,n-1); printf("ソート後のデータは以下の通り\n"); for(i=0;i<=n-1;i++) printf("%d ",a[i]); } int quick_sort(int *a,int start,int end) { int pivot; if(end-start>0){ pivot=partition(a,start,end); quick_sort(a,start,pivot-1); quick_sort(a,pivot+1,end); } } int partition(int *a,int start,int end) { int i,j,pivot,tmp; i=start-1; j=end; pivot=a[end]; while(1){ while(a[++i]<pivot); while(i<--j && a[j]>pivot); if(i>=j) break; tmp=a[i]; a[i]=a[j]; a[j]=tmp; } a[end]=a[i]; a[i]=pivot; return i; }

  • セグメンテーション違反

    環境はLinux・C言語です。 #include<stdio.h> #include<string.h> struct book{ char author[256]; char title[256]; char publisher[256]; int year; }; int main(void); int main(void) { FILE *fp1,*fp2; struct book data[256]={0},dummy={0}; char author[256]; char title[256]; char publisher[256]; int year; int i=0,j=0; fp1=fopen("biblio.txt","r"); while(fscanf(fp1,"%s,%s,%s,%d\n",&author[0],&title[0],&publisher[0],&year)!=EOF){ strcpy(&data[i].author[0],author); strcpy(&data[i].title[0],title); strcpy(&data[i].publisher[0],publisher); data[i].year=year; i++; } j=i; fclose(fp1); while(1){ for(i=0;i<256;i++){ if(data[i].year > data[i+1].year){ dummy=data[i]; data[i]=data[i+1]; data[i+1]=dummy; break; } } if(i==256) break; } fp2=fopen("biblio2.txt","w"); for(i=0;i<j;i++){ fwrite(&data[i],sizeof(struct book),1,fp2); } fclose(fp2); return(0); } 以上のソースで、セグメンテーションエラーが出ます。 問題は while(fscanf(fp1,"%s,%s,%s,%d\n",&author[0],&title[0],&publisher[0],&year)!=EOF){ の部分だとは思うのですが、どう改善すればいいのかわかりません。 どなたかわかる方お願い致します。 ちなみに、biblio.txtの内容は B.W.Kernighan & D.M.Ritchie,The C Programming Language,Prentice Hall,1988 H.M.Deitel & P.J.Deitel,C How to Program,Prentice Hall,2001 J.R.Hanly & E.B.Koffman,Problem Solving and Program Design in C,Addison-Wesley,2002 D.M.Etter,Introduction to C,Prentice Hall,1999 H.H.Tan & T.B.D'Orazio,C Programming for Engineering and Computer Science,McGraw-Hill,2000 です。

  • セグメンテーション違反

    穴掘り方というやり方で迷路を作っています。 とりあえずすこしだけ作ってみて実行したらセグメンテーション違反が起こってしまいました。 解説お願いします。 次のサイトを参考にしています。ttp://www.ced.is.utsunomiya-u.ac.jp/lecture/2009/prog/p3/kadai4/5.html #include<stdio.h> #include<stdlib.h> #include<time.h> #define A 51 #define B 51 /*51ラ51マスの迷路*/ void initialize(int *x,int *y,int map[A][B]);  /*最初のステージ作成と座標決定*/ int dig(int *x,int *y,int map[A][B]);   /*道を作る*/ int main(void) { int x,y;   /*現在の座標*/ int map[A][B];    initialize(&x,&y,map); dig(&x,&y,map); map[1][0] = 2; map[A-2][B-1] = 2; for(y=0;y<B;y++){ for(x=0;x<A;x++){ if( map[x][y] == 0){ printf(" "); }else if( map[x][y] == 1){ printf("■"); }else if( map[x][y] == 2){ printf("..") ; } } printf("\n"); } } void initialize(int *x,int *y,int map[A][B]) { int i,h; for(i=0;i<A;i++){ for(h=0;h<B;i++){ map[i][h]=1; } } do{ *x=rand()%A; *y=rand()%B; }while(*x!=0 && *x!=A-1 && *y!=0 && *y!=B-1); } int dig(int *x,int *y,int map[A][B]) { int r,c,dx,dy,count=0; do{ r = rand()%4; switch(r){     /*道を進める方向を決める*/ case 0: dx = 0; dy = -1; break; case 1: dx = -1; dy = 0; break; case 2: dx = 0; dy = 1; break; case 3: dx = 1; dy = 0; break;    } if(*x+dx*2 <= 0 || *y+dy*2 <= 0 || *x+dx*2 >= A-1 || *y+dy*2 >= B-1 || map[*x+dx*2][*y+dy*2] == 0){ c = 0; count++; if(count ==4){     /*4方向とも進めなかったらループを抜ける*/ break; } }else if(map[*x+dx*2][*y+dy*2] == 1){ map[*x+dx][*y+dy] = 0; *x = *x + dx*2; *y = *y + dy*2; c =1; } }while(c==0); }

  • reallocとstrtokの併用について

    fscanfで文字列を読み込み、strtokでカンマ区切りにするという関数を作りたいのですが、 reallocすると先頭から徐々にデータが文字化けしていきます。 まず最初に4つ分のchar*を取ります。 もし、5つ目が見つかったらさらに4つ増やし、9つ目が見つかったらさらに。。。というようになっております。 n個目の判定はcntがn-1で真になり、reallocが成功したら個数を増やすようになってます。 5つ目が見つかった時点では出力に問題は無いのですが、6個目から侵食が始まっていきます。 原因がどうしても自分では分からなかったので、誰かお願い致します。 words.txtの内容(末尾改行なし) iii,jjj,kkkkkkkkk,l,m,n,ooooo,pppppppp,a,s,d,f,g main.c #include<stdio.h> #include<stdlib.h> #include<string.h> #include"C:\borland\bcc55\Include\malloc.h" int readlinefile(FILE *fp,char **words){ int cnt=0,len; char *line=(char *)malloc(256); char *tmp; if(line==NULL) return 0; if(fscanf(fp,"%s",line)!=EOF){ if((tmp=(char *)realloc(line,sizeof(char)*(strlen(line)+1)))==NULL){//できるだけメモリを節約してみる return 0; }else{ line=tmp; } len=strlen(line); printf("line:%d:%d:%s\n",len,_msize(line),line); if(len>1){//ファイル終端の改行を排除 int i; char *tok=strtok(line,",");//カンマで区切ったアドレスを得る while(tok){ if(cnt==0)printf("tok:1st:%x\n",tok); if(cnt>3&&cnt%4==0){//サイズが足りなくなった時 char **tmp2; if((tmp2=(char **)realloc(words,sizeof(char *)*(4+4*(cnt%4))))==NULL){ printf("words realloc ERROR\n"); break; }else{ printf("realloc\n"); words=tmp2;//reallocを適用 } } words[cnt]=tok; if(cnt){ printf("line(func)"); for(i=0;i<len+1;i++){ printf("%c",words[0][i]); } printf("\n"); } tok=strtok(NULL,","); printf("words[%d]:%x:%s\n",cnt,words[cnt],words[cnt]); printf("\n"); printf("tok:%d回目:%x\n",cnt+1,tok); cnt++; } return cnt;//正常終了した }else{ free(line); } } return 0; } int main(){ FILE *fp=fopen("words.txt","r"); if(fp){ int cnt=1; while(cnt){ int i; char **words=(char **)malloc(sizeof(char *)*4); words[0]=NULL; cnt=readlinefile(fp,words); printf("mainに戻りました\n"); if(cnt) printf("words:%d\n",cnt); for(i=0;i<cnt;i++){ printf("words[%d]:%x:%s\n",i,words[i],words[i]); } free(words[0]); words[0]=NULL; printf("\n"); free(words); } }else{ printf("file open ERROR\n"); } return 0; } 実行結果 なぜかコピペできないので実行するか斧でダウンロードお願いします。 http://www1.axfc.net/u/3352789.txt 全てまとめたもの http://www1.axfc.net/u/3352796.zip

  • C言語でセグメンテーションエラーの原因がわからず困っています。

    こんにちは。いつもお世話になっております。 C言語なのですが、何故かプログラムを実行するとセグメンテーション違反が表示されてしまい全く動きません。皆さんのお力を貸して頂けないでしょうか。 以下が問題のプログラムです。 前提条件: ・別プログラムによりfile.txtは末尾に文章が追加され続けている ・本プログラムは永劫的に動き続ける #include<stdio.h> #include<stdlib.h> #include<string.h> #include<unistd.h> #include<errno.h> #include<signal.h> #include<sys/types.h> int main () { int i = 1, a; FILE *fp, *fp2; char *tok; //NULLを入れて初期化 char buf[1024] = ""; char str[1024] = ""; char str2[1024] = ""; //出力するファイルを開く if ((fp2 = fopen ("out.txt", "a")) == NULL) { printf ("out.txt:open error\n"); exit (-1); } while (1) { //何度もfopenするのでループ二週目以降は一旦fpを閉じる if (str2 != NULL) { fclose (fp); } //一度読み込み、2週目以降もさらに読み込み続ける if ((fp = fopen ("file.txt", "r")) == NULL) { printf ("file.txt:open error\n"); exit (-1); } //str2はループ2週目以降で使われる if (str2 != NULL) { while (1) //新しい行を見つけ出す { fgets (str, 1024, fp); if (strstr (str, str2) != NULL) { printf ("前回の最終行です:%s\n", str); break; } } } else { printf ("str2はNULLです:%s\n", str2); } //fopenで読み込んだ現段階のテキストファイルをout.txtに移す while (1) { if( (fgets (str, 1024, fp) ) == NULL)break; if ((a = strlen (str)) >= 2) { str[a - 1] = '\0'; } else { printf ("抽出した文字列が1文字以下です:%s\n", str); break; } if (strlen (str) >= 17) { strcpy (str2, str); } else { printf ("抽出した文字列が16文字以下です:%s\n", str); break; } printf ("%s\n", buf); fprintf (fp2, "%s\n", buf); strcpy (buf, ""); strcpy (str2, str); } printf ("これが検索語です:%s\n", str2); } fclose (fp2); return 0; } プログラムの内容は、 更新され続けるテキストファイル(file.txt)から、別のテキストファイル(out.txt)に出力するというプログラムです。(file.txtの内容を若干変えつつ、out.txtに出力することが本来の目的ですが、その部分は省略させて頂きました。) fopenで開くと、「その時点まで」のfile.txtしか開かれません。更新され続けているfile.txtの内容をコンスタントに読み取る為に、while文でfopenし続ける方法を取っていますが、そうするとout.txtに移し終わった行まで読み込んでしまい重複した文章をout.txtに移すことになりますので、strstrを使い、「前回fopenで開いたfile.txt」の最終行を検索してその位置からまたout.txtに移す、という方法を取りました。しかし、結果は何故かセグメンテーション違反でした。 以上のプログラムや私の意図する所で何か気づかれた点や、おかしいと思われた点等ありましたら是非ご教授頂きたく思います。 どんな些細なことでも構いませんので、教えて頂けないでしょうか。 環境はCentosです。どうぞよろしくお願いします。

リモコンが繋がらない
このQ&Aのポイント
  • エレコムのリモコンを家のテレビに接続しようとしていますが、接続ができません。
  • 接続用のコマンドを入力すると、リモコンからは音がなるもののボタンが反応しません。
  • エレコムのリモコンの接続に関する問題が発生しています。
回答を見る

専門家に質問してみよう