1
    FILE *file = fopen(argv[1], "r");
    if(file != NULL){
        char command[MAX_BUFFER];
        while(fgets(command, MAX_BUFFER, file) != NULL){ //read line
            //operations
        }
        fclose(file);
    }
    else write(fileno(stderr), ERROR_MESSAGE, strlen(ERROR_MESSAGE));

私は、ファイルから1行ずつ読み取り、実行する非常に基本的なUNIXシェルの実装に取り​​組んでいます。上記のコードからfclose()、valgrindがこのファイル記述子を開いたままにしたと言っているように見えるので、なぜ失敗するのかを理解しようとしています。

リークサマリーの「まだ到達可能な」568バイトがfclose()何らかの理由で失敗したことを示していると仮定して正しいですか?

==25428== FILE DESCRIPTORS: 4 open at exit.
==25428== Open file descriptor 3: test
==25428==    at 0x4F186B0: __open_nocancel (syscall-template.S:82)
==25428==    by 0x4EAC628: _IO_file_fopen@@GLIBC_2.2.5 (fileops.c:233)
==25428==    by 0x4EA1265: __fopen_internal (iofopen.c:93)
==25428==    by 0x400C0C: main (in /home/Desktop/sh)
==25428== 
==25428== Open file descriptor 2: /dev/pts/0
==25428==    <inherited from parent>
==25428== 
==25428== Open file descriptor 1: /dev/pts/0
==25428==    <inherited from parent>
==25428== 
==25428== Open file descriptor 0: /dev/pts/0
==25428==    <inherited from parent>
==25428== 
==25428== LEAK SUMMARY:
==25428==    definitely lost: 0 bytes in 0 blocks
==25428==    indirectly lost: 0 bytes in 0 blocks
==25428==      possibly lost: 0 bytes in 0 blocks
==25428==    still reachable: 568 bytes in 1 blocks
==25428==         suppressed: 0 bytes in 0 blocks
4

3 に答える 3

1

そうそう、戻り値をチェックして、簡単な説明を得るために perror も貼り付けます。まだ開いていることを確認したい場合は、lsof を試してください。

于 2013-01-18T05:12:49.050 に答える
0

表示されているコードは問題ないようです。しかし、あなたの質問に答えるために:可能性が高いですが、問題はどこかにあります;-)

プログラムをデバッグするには、「操作」をコメントアウトして、空のループを作成します。valgrindはまだ文句を言いますか?

いいえ:問題は、「operations」という名前のコードにある可能性が非常に高いです。

コメントを削除し、(-g)のデバッグ記号を使用してコンパイルし、次のオプションを指定してvalgrindを使用します。valgrind--leak-check = yes --show-reachable = yes --track-origins = yes yourprogram

はい:(非常にまれですが)何か他のものが壊されたので、もっとコメントされたコードでvalgrindしてみてください。

コンパイル時にバグを見つけるには、コンパイラのフラグを使用します(たとえば、gccには-Wall -Wextra -Wwrite-strings -Wformat = 2 -Wformat -Wformat-security -D_FORTIFY_SOURCE = 2などがあります)。

そして、静的アナライザー、例えばllvm / clangを利用します(clangでコンパイルします--analyze yourprogram.c)

于 2013-01-18T08:17:59.123 に答える
0

私の操作をコメントアウトするという@rockdabootの提案は、私がまだメモリを失っていることを示しましたが、少なくとも私はそれがfcloseからではないことを知っています...ヒントをありがとう、みんな! デバッグに戻ります!

于 2013-01-18T15:41:29.810 に答える