- 締切済み
C言語について
以下のプログラムについてです test.txtから単語を読み込んでその異なる単語の数を求めるプログラムです。 #include<stdio.h> #include<stdlib.h> #include<string.h> #include<stddef.h> #include<ctype.h> #define NMAX 80 #define LMAX 5000 void count(FILE*, int); void all_words(FILE *); FILE *fp, *fp2; char *fn="test.txt"; char *fn2="total word.txt"; const char *ignore="\n !?()*-;:.,_\"[]"; int main(void){ int p=0, x=0, c, l, t=0,k=0; char word3[LMAX][NMAX]; char word1[NMAX]; char word2[NMAX]; char *tp; char *tp2; if((fp=fopen(fn,"r"))==NULL){ printf("Can't open '%s'.\n",fn); return -1; } if((fp2=fopen(fn2,"w"))==NULL){ printf("Can't open '%s'.\n",fn2); return -1; } for(c=0;c<LMAX;c++){ if(fgets(word3[c],NMAX,fp)==NULL)break; p++; } for(c=0;c<p;c++){ for(x=0;x<NMAX;x++){ word1[x]=tolower(word3[c][x]); } tp=word1; while((tp2=strtok(tp,ignore))!=NULL){ if(*tp2=='\''){ if(*(tp2+1)=='`'){ t=1; } tp2++; } free(tp); strcpy(word2,tp2); k=l=strlen(word2)-1; if(word2[k]==('\'' & l)){ word2[l]='\0'; } if(word2[0] =='\'' &&t==0){ if(word2[1]!='\0'){ fputs(word2+1,fp2); fputc('\n',fp2); } } else{ if(word2[0]!='\0'){ fputs(word2,fp2); fputc('\n',fp2); } } tp=NULL; } } fclose(fp); fclose(fp2); all_words(fp2); return 0; } void all_words(FILE* fp2){ char word3[NMAX]; int n=0; if((fp2=fopen(fn2,"r"))==NULL){ printf("Can't open '%s'.\n", fn2); return; } for(;;){ if(fgets(word3, NMAX,fp2)==NULL){ break; } n++; } fclose(fp2); count(fp2,n); } void count(FILE* fp2, int n){ int c, x, y=0; char *m=(char *)malloc(n*NMAX); char *xp; char *yp; if((fp2=fopen(fn2,"r"))==NULL){ printf("Can't open '%s'.\n", fn2); free(m); return; } for(c=0,xp=m; c<n;c++,xp+=NMAX){ fgets(xp,NMAX,fp2); } qsort(m,n,NMAX,(int (*)(const void*, const void*))strcmp); c=1; for(x=0,xp=m,yp=m+NMAX;x<n-1;xp+=NMAX,yp+=NMAX,x++){ if(strcmp(xp,yp)==0){ y++; c++; } else{ c=1; } } printf("KIDN OF WORD:%d\n",n-y); free(m); fclose(fp2); } このプログラムについてメモリリークになってしまうのですが 確保していないメモリー領域に代入しているのが原因らしいのですが 具体的にどこを直せば良いのでしょうか? よろしくお願いします
- みんなの回答 (2)
- 専門家の回答
みんなの回答
- wormhole
- ベストアンサー率28% (1626/5665)
>このプログラムについてメモリリークになってしまうのですが どうやってメモリリークと判断されたんですか? >確保していないメモリー領域に代入しているのが原因らしいのですが その原因(確保していないメモリー領域に代入している)はどうやって調べたんですか? そこまでわかっているなら、どこを直せばいいかもわかってそうな気がしますが。 #1でもあげられている >free(tp); は、何をfreeしているつもりなんでしょうか。 #メモリリークといわれてるのは、たぶんここなんだとは思いますが。 また >k=l=strlen(word2)-1; >if(word2[k]==('\'' & l)){ も何をやってるつもりなのかさっぱりわかりません(文字"'"とword2の長さのandをしてどうするつもりなんだろう)
- kmee
- ベストアンサー率55% (1857/3366)
http://okwave.jp/qa/q8131021.html と比較したら、指摘のあった sprintf(xp+strlen(xp)-1," (%d)",count); を削除しただけ、に見えますが、変更点はそれでよろしいでしょうか? 前回も書いたとおり、[確保していないメモリー領域に代入しているのが原因らしいのですが]とわかっているのなら、それを探すのがセオリーです。 でも、実際のところ、いろいろと変なことをしているので、そちらの方が原因となっているように思います。 > while((tp2=strtok(tp,ignore))!=NULL){ 前回も指摘しましたが、strtokの使い方が変です。 マニュアルや参考書をよく読んでください。 > free(tp); freeするべきメモリを確保していないようですが。 tp=word1; で、char word1[NMAX]; で、ここからfree(tp)迄の間にtpが変化するような処理は無いので、この文は free(word1); と同じことになります。malloc など で確保していない領域をfreeで解放できるわけがありません。 > fclose(fp2); > count(fp2,n); fcloseして無効になったFILE * fp2を引数に使って呼び出しています。 文法上可能ですが、通常のプログラミング作法としては有り得ないことです。 実際に、count関数では、if((fp2=fopen(fn2,"r"))==NULL){ と、受け取った値をまったく使っていません。 これなら,fp2を渡す意味はありません。単に、count関数内のローカル変数として定義すればいいだけです。 真ん中あたりのword1,word2を使った処理にも問題ありそうですが、何を意図したものかがまったく理解できませんでした。