1

次のコードがあります。

char *passwordFunc(const char *s)
{
    static char *pw = NULL;
    if (strlen(s)) {
        pw = s;
    } 
    return pw;
}

void keyboard_interactive(const char *name, int name_len, const char *instr, int instr_len, 
                          int num_prompts, const LIBSSH2_USERAUTH_KBDINT_PROMPT *prompts, LIBSSH2_USERAUTH_KBDINT_RESPONSE *res, 
                          void **abstract)
{
    char *text = passwordFunc("");
    res[0].text = strdup(text);
    res[0].length = strlen(text);
}

デバッガーによると、 の行に到達するたびstrdup(text)EXC_BAD_ACCESS (code=2, address=0x0).

何が起こっているのか、それを修正する方法について何か提案はありますか? 前もって感謝します。

4

2 に答える 2

4

passwordFunc("")返品中NULLです。これを に渡すと、有効な C 文字列strdupが必要になるため、セグメンテーション違反が発生します。strdupエラー メッセージがアドレスを参照し0x0ていることは、プログラムがヌル ポインターを逆参照していることを示しています。

現在、はゼロであり、ゼロは false と評価されるため、passwordFunc("")戻ります。NULLstrlen("")

の一部の実装はstrdup、渡されたときに空の文字列を返しますNULL。このコードは、そのような実装を想定して書かれているようです。コンパイラのライブラリの動作が異なります。

strdupこのコードが想定する方法で動作する の独自の実装を提供することで、おそらく最も簡単にコードを修正できます。

char *strdup(const char *s) {
    size_t len = (s == NULL) ? 1 : strlen(s) + 1;
    char *result = malloc(len);  
    if (result != NULL) 
        if (len>1)
            memcpy(result, s, len);                       
        else
            *result = 0;
    return result;                           
}

余談ですが、ではなくpasswordFunc実際に返すべきであり、同様にすべきであるとコメントします。コンパイラはおそらくこれについて警告するので、それらの警告に注意する必要があります。const char*char*pwconst char*

于 2012-05-12T20:37:46.743 に答える
0

あなたの問題は、プロンプトがなくても、コールバック関数が時々呼び出されることです。そのため、オブジェクトに何かを設定する必要があるかどうかを確認する必要がありresます。

このコード スニペットは問題を解決します。

void keyboard_interactive(const char *name, int name_len, const char *instr, int instr_len, 
                          int num_prompts, const LIBSSH2_USERAUTH_KBDINT_PROMPT *prompts, LIBSSH2_USERAUTH_KBDINT_RESPONSE *res, 
                          void **abstract)
{
    if( num_prompts > 0 ) {
        res[0].text = strdup(passwordFunc(""));
        res[0].length = strlen(passwordFunc(""));
    }
}
于 2012-06-29T22:25:59.073 に答える