2016-08-20 23 views
2

現在、関数fscanfを使用して、charとfloatポイントのファイルを解析しています。結果を印刷し、valgrindでメモリチェックしました。 今、印刷は正しいですが、常にの間違いなくメモリが失われています()。C関数fscanf(メモリ損失あり)

これはサンプルコードです:

FILE* table; 
table = fopen("table", "r"); 
double mass; 
while (fscanf(table, %lf ", &mass) != EOF){ 
    printf("mass: %lf\n", mass); 
} 

--leak-check=fullオプションとvalgrindのは言う:

==7104== 513 bytes in 1 blocks are definitely lost in loss record 52 of 62 
==7104== at 0x100008EBB: malloc (in /usr/local/Cellar/valgrind/3.11.0/lib/valgrind/vgpreload_memcheck-amd64-darwin.so) 
==7104== by 0x1001EF66C: __parsefloat_buf (in /usr/lib/system/libsystem_c.dylib) 
==7104== by 0x1001ED9EF: __svfscanf_l (in /usr/lib/system/libsystem_c.dylib) 
==7104== by 0x1001E1492: fscanf (in /usr/lib/system/libsystem_c.dylib) 
==7104== by 0x100000F3F: main (in ./prtm) 

は、私はそれは形式の問題だと思います。私も%ffloatを使用しようとしましたが、もっと似たようなエラーが出ます。 誰かが間違っていることを教えてもらえますか?

+6

あなたはファイルを閉じないでください。 – 2501

+0

これをおそらく関連する理由として排除するだけです。欠落している 'fclose'の追加メモリ損失レポートを取得しますか? (asはhttp://stackoverflow.com/q/31630583/2564301に従って報告する必要があります)そして、ファイルを適切に閉じると、このファイルは消えませんか? – usr2564301

+1

'valgrind'を実行し、あなたのコードが明示的にメモリを割り当てていないのに、' valgrind'が終了時にメモリを使用していると報告している場合は、 'fopen'のように、つかいます。メモリを割り当てずに追加のライブラリ関数を呼び出さなくても、終了時に 'valgrind'報告メモリが使用中に残っている場合は、正しい*除外*ファイルが' valgrind'のあなたのバージョンで利用できません現在実行しているOSそれは起こる、ちょうどそれらのMacを実行してください。 –

答えて

3

コードフラグメント内のファイルにfclose()のファイルを掲載していませんが、これは問題を引き起こす可能性があります。いずれにしても、fclose()ファイルを必ず確認してください。

関数fscanfは、独自の目的でメモリを割り当てているようで、プログラム終了時に解放しません。 valgrindは通常、このような避けがたいメモリリークを知っており、何らかの理由でこれを見逃してしまい出力を抑制します。

このメッセージは、コードに問題があるとは思われません。報告された失われたブロックは、その内部浮動小数点パーサー__parsefloat_bufの場合、コールスタックからわかるように、OS/Xバージョンfscanf()によって割り当てられます。

もっと正確に言えば、LibCのソースコードはhttp://opensource.apple.comLibc-763.11/stdio/vfscanf-fbsd.c:965)から入手でき、ブロックは終了時にフリーズされているはずです。

これであなた自身で試してみることもできますが、このコードをプロダクションコードに追加することはおすすめしません。ラッドレクサスで指摘したように

#include <stdlib.h> 
#include <pthread.h> 
#include <sys/cdefs.h> 

... 

free(pthread_getspecific(__LIBC_PTHREAD_KEY_PARSEFLOAT)); 
pthread_setspecific(__LIBC_PTHREAD_KEY_PARSEFLOAT, NULL); 

代わりに、あなたはこの質問に示すように、この警告を無視するvalgrindのを教えてください:On OSX Valgrind reports this memory leak, Where is it coming from?

+1

私はあなたと一緒にいます - しかし、この状況をどのように区別することができるかを示しています(割り当ての呼び出しスタックのライブラリ関数のみです。 'fscanf'の後に' free'を実行する必要があります)、コードが実際に何か問題を起こしている状況から、本当に答えが増えるでしょう。 – tofro

+1

「あまりない?ジョナサン・レフラーは、バングラディンにそれを無視するように言います(http://stackoverflow.com/a/9039682/2564301)。 – usr2564301

+1

割り当てられたメモリを解放しないライブラリに関する注意:プログラムの実行中にライブラリがメモリを解放することは一般的には実現可能ではありません。実践的なメカニズムはありません。プログラムを終了する直前に出口ハンドラを追加してメモリを解放することもできますが、なぜですか?とにかくプログラムの全記憶が瞬時に消えてしまうという利点はありません。 – hyde

関連する問題