2016-10-24 7 views
1

"struct passwd"の使用に5ブロックのメモリリークを隔離しました。無駄にいくつかの異なる無料の(ユーザー)呼び出しを試してみました。この構造体はどのように解放されることになっていますか?トピックに関するいくつかの異なるSOの質問が、私はこの特定の構造体をどのように処理する必要があるかについてのほとんどのドキュメントを見つける。プログラムは別途問題なく動作します。ありがとう。struct passwdはメモリリークの原因です - どのように正しく解放するのですか?

#include <assert.h> 
#include <pwd.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <unistd.h> 
#include <sys/types.h> 

int main() { 
    pid_t pid = getpid(); 
    uid_t uid = getuid(); 
    struct passwd *user = getpwuid(uid); 
    unsigned int bufferMaxLen = strlen(".dir.") + strlen(user->pw_name) + 10; 
    char* dirName = malloc(bufferMaxLen * sizeof(char)); 
    assert(dirName != NULL); 
    sprintf(dirName, "%s.dir.%d", user->pw_name, pid); 

    printf("bufferMaxLen is: %d\n", bufferMaxLen); 
    printf("Directory name is: %s\n", dirName); 

    free(dirName); 
    return 0; 
} 
+1

メモリがリークしていることをどのように知っていますか? 'man getpwuid'は明示的に" *戻り値は静的領域を指し、getpwent(3)、getpwnam()、またはgetpwuid()の後続の呼び出しによって上書きされるかもしれません(返されたポインタを解放しないでください(3)を参照してください。)* " –

+0

' getpwuid'の正確な動作はプラットフォーム固有のものだと思います。 – molbdnilo

+0

valgrind <実行ファイルの名前> – Chris

答えて

2

このコードでは、実装固有のライブラリ機能のように見えます。ライブラリが最初に関数を呼び出すときにライブラリを割り当てて、それを解放しないことはかなり普通です。通常の実行中に解放する方法や機会がなく、終了ハンドラで単一のメモリ割り当てを解放することは全く意味がありません。プログラム終了直後に解放される。

この種の割り当ては静的なデータと考えることができますが、必要なときにのみバッファ/構造体への静的ポインタが割り当てられます。関連する関数が呼び出されない場合は、メモリの使用量が少なくて済みます。欠点は、あなたの質問で実証されたメモリアナライザの混乱は言うまでもなく、関数が呼び出されると少し複雑なコード、ランタイムコスト、メモリの使用です。

Valgrindのようなツールでは、この種の「リーク」を隠すフィルタを無視しています。

+0

この漏れが「正常」であり、Valgrindがそれを無視するように設定する必要があるという良い点は、あなたが証明できるようにしていない限りです:) – LHMathies

+0

面白い!そのような動機はなく、ちょうど漏出をチェックするという練習にある。 – Chris

3

あなたは、あなた自身のstruct passwordgetpwuid_r/etc/passwdを読み取るためのバッファを供給することによって、メモリの割り当てを制御することができます。

(これはリエントラントにも役立ちます。その理由は、この関数の接尾辞は_rです。接尾辞のないバージョンでは、グローバルバッファを1つ割り当てることができます)。

関連する問題