4

以下のコード セクションでセグメンテーション違反が発生しました: (この segfault に関して、1 つのトピックで 2 つの質問をしています)

req_cw(ECM_REQUEST *er, int32_t flag, int32_t reader_types){

    LL_NODE *ptr;
    for (ptr = er->matching_rdr->initial ; ptr ; ptr = ptr->nxt) {
        if (ptr == er->fail)
            break;
    rdr = (struct s_reader*)ptr->obj;
    we_equest(rdr->fd, er);
    }
}

ご覧のとおり、制御構造を使用しif(ptr->obj && ptr)てもptr(またはポインターptr->objにならないnull)、それを防ぐことはできず、値を出力しようとしたときにセグメンテーション違反が発生した後ptr->obj

print ptr->obj 、gdbは次のように述べています:

(gdb) print ptr $1 = (LL_NODE *) 0x149

(gdb) × 0x149

0x149: アドレス 0x149 のメモリにアクセスできません

私の質問は次のとおりです。このセグメンテーション違反を防ぐにはどうすればよいですか?このセグメンテーション違反が発生する理由と修正方法を教えてください。

  1. この segfault に関して、 gdb を使用しているときに、フレーム 1 (segfault が発生した 1 フレーム前) を確認したところ、

er->cw私の質問は、が と等しくない"\000 <repeats 15 times>" 場合、どのように制御できますか?er->cw"'\000' <repeats 15 times"

私はこれをしました、それが正しくないことを知っています(そして私は何かを逃しました)、それが私がここで尋ねる理由です

if (er->cw)
req_cw(er , ...)

問題は追加if(er->cw)です。は文字であり、整数のように振る舞うべきではないと思いますcwが、それがゼロでないことを確認する方法がわかりませんか?、つまり、 gdb で確認したときにこの行を再度使用してもer->cw、値は "'\ 000'" が渡されているので、if 制御ブロックを使用er->cwして '\000' と等しくない場合を確認するにはどうすればよいですか?

前もって感謝します。

4

2 に答える 2

3

As you see, even with the control structure with if(ptr->obj || ptr) to be sure ptr (or ptr->null won't be null pointer)

いいえ...実際には、どちらもNULLになることは保証されません。これにより、セグフォルトが発生します。は終了する前に両側||を評価しますが、ロジックを逆方向に設定します。あなたが欲しかったので、それらを反転する必要があります。&&NULL

if(ptr && ptr->obj)

値 ptr->obj を出力しようとしたときのセグメンテーション違反の後:
print ptr->obj 、gdb は言う:
...
0x149: アドレス 0x149 のメモリにアクセスできません

有効なアドレスを見たことがありません0x149。使用しているハードウェア プラットフォームは何ですか?


er->cw は "\000" です。私の質問は、er->cw が "'\000' と等しくない場合、どうすれば制御できるかということです。

よくわかりませんが、 の構造を教えてくださいerer->cwそれはchar *タイプであり、に設定されていると言っています"\000 <repeats 15 times>"か?

于 2013-03-04T14:56:07.470 に答える
1

ご覧のとおり、 if(ptr->obj || ptr) を使用した制御構造でも、確実に ptr (または ptr->null は null ポインターにはなりません)

問題は、テストを実行する順序です。コンパイル時にptr->obj最初に実行されるため、ptr無効なメモリにアクセスしている場合はobjメンバーを取得してください。テストの順序を逆にするif (ptr || ptr->obj)

しかし、それはまだ正しくありません...あなたのORロジックも間違っています。コードは...

if ((ptr != NULL) && (ptr->obj != NULL))
{
   // use the pointer
}
于 2013-03-04T14:47:27.103 に答える