- 締切済み
C言語について
以下のプログラムについてです。 test.txtというファイルを読み込み、その中の異なる単語の数を求めるプログラムです。 #include<stdio.h> #include<stdlib.h> #include<string.h> #include<ctype.h> #include<stddef.h> #define NMAX 80 #define LMAX 5000 void count(FILE*, int); void all_words(FILE *); FILE *fp, *fp2; char *fn="alice.txt"; char *fn2="total word.txt"; char *ignore="\n !?()*-;:.,_\"[]"; int main(void){ int p=0, x, count, l, t=0,k=0; char name[LMAX][NMAX], word1[NMAX], word2[NMAX]; char *tp, *tp2; if((fp=fopen(fn,"r"))==NULL){ printf("Can't open '%s'.\n",fn); exit(1); } if((fp2=fopen(fn2,"w"))==NULL){ printf("Can't open '%s'.\n",fn2); exit(1); } for(count=0;count<LMAX;count++){ if(fgets(name[count],NMAX,fp)==NULL)break; p++; } for(count=0;count<p;count++){ for(x=0;x<NMAX;x++){ word1[x]=tolower(name[count][x]); } tp=word1; while((tp2=strtok(tp,ignore))!=NULL){ if(*tp2=='\''){ if(*(tp2+1)=='`') t=1; tp2++; } 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); exit(1); } for(;;){ if(fgets(word3, NMAX,fp2)==NULL) break; n++; } fclose(fp2); count(fp2,n); } void count(FILE* fp2, int n){ int count, x, y=0; char *m=(char *)malloc(n*NMAX); char *xp,*yp; if(m==NULL){ return ; } if((fp2=fopen(fn2,"r"))==NULL){ printf("Can't open '%s'.\n", fn2); exit(1); } for(count=0,xp=m; count<n;count++,xp+=NMAX){ fgets(xp,NMAX,fp2); } qsort(m,n,NMAX,(int (*)(const void*, const void*))strcmp); count=1; for(x=0,xp=m,yp=m+NMAX;x<n-1;xp+=NMAX,yp+=NMAX,x++){ if(strcmp(xp,yp)==0){ y++; count++; } else{ count=1; } } printf("KIDN OF WORD:%d\n",n-y); if(m){ free(m); m=NULL; printf("%p\n",m); } fclose(fp2); } このプログラムを実行するとメモリリークになってしまいます どうしたら良いでしょうか?
- みんなの回答 (4)
- 専門家の回答
みんなの回答
- wormhole
- ベストアンサー率28% (1626/5665)
プラットホームがわかりませんがLinuxなどvalgrindが使えるなら、valgrindで調べてみるとか。
- Tacosan
- ベストアンサー率23% (3656/15482)
本題とは全く関係ありませんが, スコープが違うのでそれ自体は問題ありません>#1. ただし, 関数 count の内部では「count と書けば変数」になるので関数 count を直接再帰的に呼び出すことはできません.
- hirotn
- ベストアンサー率59% (147/246)
m=NULL; printf("%p\n",m); メモリを開放(free)した後でこれ必要かしら?と考えております。 Windows7+gccで、Gudenburg project のalice in wonderlandを読ませた場合、落ちずに終わります。 箇所の特定にgcc+gdbを使うならば、 gcc -g -O0 プログラム名.c -o foo.exe でコンパイルして、 gdb foo.exe で起動すると、”(gdb)”というプロンプトが出るので、 b 行数 でストップしたいプログラムの行数を指定します。次に、runを実行するとbで設定した箇所(ブレークポイント)まで実行します。それまでの箇所にエラーがあれば、落ちます。例えば無理やりバッファオーバーランさせると、 Breakpoint 1, main () at alice.c:31 31 scanf("%d", i); (gdb) n 1235 3 [main] a 2564 exception::handle: Exception: STATUS_ACCESS_VIOLATION 994 [main] a 2564 open_stackdumpfile: Dumping stack trace to a.exe.stackdump 問題の箇所が特定できるまでブレークポイントで絞り続けます。問題の箇所がわかったら原因を考えます。箇所が分からない状態で悩むのはかなり大変な作業です。
- Trick--o--
- ベストアンサー率20% (413/2034)
リークの原因かはわからないが void count(FILE* fp2, int n){ int count, x, y=0; Cでは関数名と変数名は同じにできなかったと思う。