- 締切済み
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; 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++; } strcpy(word2,tp2); l=strlen(word2)-1; if(word2[l]==('\'' && 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++; } 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)
- 専門家の回答
みんなの回答
- kmee
- ベストアンサー率55% (1857/3366)
訂正します。 strtokについては、 tp=NULL ; を見逃していました。
- kmee
- ベストアンサー率55% (1857/3366)
指摘されたところを直したつもりになっているようですが、かえって悪化してます。 > while((tp2=strtok(tp,ignore))!=NULL){ しつこいようですけど、これは何を意図しているのですか? strtokの説明は読んだのですか? この内容だと ・word1がignoreの中の文字だけ構成される場合→ループ脱出 ・それ以外→whileが無限ループになる となります。 このstrtokで何をしたいのですか? > if(word2[l]==('\'' && l)){ 前回の指摘で変更したのでしょうけど、余計に意味がわからなくなっています。 &&演算は、0か1にしかなりません。 '\'' は0でないので、l==0のとき0,l!=0のとき1となります。つまり、このifは if ( ( (l == 0 ) && (word2[0] == 0) ) || ( ( l != 0 ) && ( word2[l] == 1) ) ) { と等価になります。' かどうかはまったく無関係です。 この判定は何を意図しているのですか? > count(fp2,n); 前回書いたのは、fcloseするな、って意味じゃありません。 count関数で if((fp2=fopen(fn2,"r"))==NULL){ と新たにfopenしているから、fp2を渡す意味が無い、と言っているのです。 渡したfp2を有効に使いたいなら、fopenせずに、fseekで先頭に戻して読み直す cont関数内でfopenするなら、 void count(int n){ FILE *fp2; と、nだけ渡して、fp2はローカル変数にすればいい。 現在のプログラムでは void count(FILE * fpx , int n){ FILE *fp2; と書いたのと同じ。fpxがまったく使われていない。 ということです。 おなじことは、all_wordでも言えます。