0

親からフォークされた子プロセスの終了ステータスにアクセスしようとしていますが、奇妙な答えが得られます。&status を指定するかステータスだけを指定するかによって、256 が返されることもあれば、負の値が返されることもあります。私は私が本当に近いことを知っています。EXIT_STATUSを取得する方法を誰かが少し助けてくれますか

これが私のコードです

pid_t  pid;
int *status;
if((pid = fork()) < 0)
    fprintf(stdout, "Error forking child process\n");

else if (pid == 0)
{
    execvp(input[0], input);
    fprintf(stdout, "Invalid process!!\n");
    _exit(EXIT_FAILURE);

}
else
{
    while (waitpid(-1, status, 0) != pid);
    fprintf(stdout, "The status is %d\n", &status);
}
4

2 に答える 2

4

使用しているポインターを初期化していないため、この動作が発生しているため、未定義の動作が呼び出されています。つまり、文字通り、何かが起こる可能性があります。(の代わりに)statusになるように変更してみてください:intint*

int status;
/* ... */
while (waitpid(-1, &status, 0) != pid);
fprintf(stdout, "The status is %d\n", status);

一方、あなたのコード:

int * status;

これにより、int へのポインターが作成され、初期化されません。

while (waitpid(-1, status, 0) != pid);

ここで、このポインターを waitpid() に渡します。これは、ポイントされた場所に書き込みます。ポインタを初期化していないため、指定されていないメモリ位置に書き込んでいます! これにより、プロセスがクラッシュしたり、他の場所で割り当てられたメモリが上書きされたりする可能性があり、後で自発的にクラッシュしたり、データが破損したりする可能性があります!

fprintf(stdout, "The status is %d\n", &status);

これは、ポインター変数のアドレスを出力します。ポインター変数が指す値ではありません! *statusの代わりに 使用すると&status、この部分が機能する可能性がありますが、まだ初期化されていないポインターを使用しています。

コンパイラの警告設定を最大 ( -Wallgcc で渡す) にして、すべてについて警告するようにすることを強くお勧めします。初期化されていないポインターの使用法をキャッチ%dし、ポインター型の値でフォーマット指定子を使用することについて警告した可能性もあります。

于 2012-11-11T03:32:54.337 に答える
0

戻り値に大きな数値や負の数値を使用しないでください。混乱を招きます。例として、32 ビット システムでは次のようになります。

int の場合: 255 は0x000000ff-1 です0xffffffff。したがって、8 つのビット ブロックのいずれかを -1 で返す場合、それらはすべて0xffまたは 255 です。

exit(1) または exit(2) または exit(3) を呼び出すか、その他の小さな正の数を呼び出すと、より適切に実行されます。WIFEXITED(&status)親では必ず最初に呼び出してください。

終了ステータスを使用して、発生した問題について何かを「伝える」ように思われるので、sysexits を試してください: http://www.gsp.com/cgi-bin/man.cgi?section=3&topic=sysexits

または単に動作することが保証されているEXIT SUCCESSor EXIT_FAILUREex: return EXIT_SUCCESS;orexit(EXIT_FAILURE); を使用します。つまり、成功または失敗をリターンとして返します。

于 2012-11-11T18:12:03.557 に答える