2011-06-24 8 views
2

メモリリークや破損に対して私のプログラムを確認しています。 setpwentを使用しているときに問題があります。 のように簡単なプログラムを考えてみましょう。私はvalgrindの中で、コードのこの部分を実行するとsetpwentはvalgrindのメモリリークを示します

#include<stdio.h> 
#include<stdlib.h> 

main() 
{ 
    struct passwd *ent=NULL; 
    setpwent(); 
     while ((ent = getpwent()) != NULL) { } 
    endpwent(); 
} 

、私はこれを取得:

> valgrind --track-origins=yes 
> --tool=memcheck --leak-check=yes --show-reachable=yes --num-callers=20 --track-fds=yes ./a.out . . . 160 (40 direct, 120 indirect) bytes in 1 
> blocks are definitely lost in loss 
> record 11 of 11 
> ==6471== at 0x4025BD3: malloc (vg_replace_malloc.c:236) 
> ==6471== by 0x411CA9C: nss_parse_service_list 
> (nsswitch.c:622) 
> ==6471== by 0x411D216: __nss_database_lookup (nsswitch.c:164) 
> ==6471== by 0x459BEAB: ??? 
> ==6471== by 0x459C1EC: ??? 
> ==6471== by 0x411D864: __nss_setent (getnssent_r.c:84) 
> ==6471== by 0x40D304F: setpwent (getXXent_r.c:127) 
> ==6471== by 0x8048469: main (in /root/workspace/cdk-examples/MMC-0.64/a.out) 
> ==6471== 
> ==6471== LEAK SUMMARY: 
> ==6471== definitely lost: 40 bytes in 1 blocks 
> ==6471== indirectly lost: 120 bytes in 10 blocks 
> ==6471==  possibly lost: 0 bytes in 0 blocks 
> ==6471== still reachable: 0 bytes in 0 blocks 
> ==6471==   suppressed: 0 bytes in 0 blocks 

は、私はそれを心配する必要がありますか? この問題を解決するにはどうすればよいですか?

2番目の質問: 私はパスワード入力を解放する必要がありそうであるように:

main() 
{ 
    struct passwd *ent=NULL; 
    setpwent(); 
     while ((ent = getpwent()) != NULL) { 
      free(ent); 
     } 
     endpwent(); 
} 

私を助けてくれてありがとう。

答えて

3

最初の質問です。とにかくsetpwentに電話する必要はないと思います。 getpwent(プロセス開始後またはendpwentの後)への最初の呼び出しで、これが最初に戻ります。

あなたは後getpwentを呼び出すが、endpwentを呼び出すことなく巻き戻しする場合にのみsetpwentを必要としています。

単一setは、(a)は私は疑うよう、全体(またはのかなりの割合)ファイルがメモリにキャッシュすることができる、特に、場合、速くend/getペアよりもおそらくあります。


2番目の質問では、あなたはそれを解放しません。 hereを参照してください。スタティックバッファ(シングルスレッド用)またはスレッドローカルストレージ(マルチスレッド用)を使用する可能性が最も高いです。

いずれの場合も、コード(a)ではなく、バッファを管理するのは呼び出しそのものです。


(A)興味深いことに、戻さentの値は確かが別の割り当てなど見える反復ごとに異なっています。

しかし、アドレスは32バイトだけ離れており、struct pwdのサイズは32バイトであるため、mallocハウスキーピング情報を介在する余地はありません。

したがって、ハウスキーピング情報はインラインではない(実際そうでない)か、個々の割り当てではなく構造の配列で実際に作業しているかのどちらかです。

次のプログラムは、この動作を示しています

#include <stdio.h> 
#include <stdlib.h> 
#include <pwd.h> 

int main (void) { 
    struct passwd *ent = NULL; 
    printf ("ent struct is %d bytes\n", sizeof(*ent)); 
    while ((ent = getpwent()) != NULL) { 
     printf ("pointer is %p, user is %s\n", ent, ent->pw_name); 
     // free (ent); 
    } 
    endpwent(); 
    return 0; 
} 

これは、出力:

ent struct is 32 bytes 
pointer is 0x4708d0, user is alan 
pointer is 0x4708f0, user is bill 
pointer is 0x470910, user is carl 
pointer is 0x470930, user is dawn 
pointer is 0x470950, user is ella 
pointer is 0x470970, user is fran 

を上記の結論に私をリードするものです。いずれにしても、私のコードでfree行のコメントを瞬時に取り除くと、コアダンプが発生し、私の理論がよりサポートされます。

今、私は私ちょうどなくなっとgetpwentソースコードを見ていたが、私は

+0

良いと合理的な答え:-)良いパズルを愛し、答えている可能性が想定 – rahman

関連する問題