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。当你将它传递给 时strdup,你会得到一个分段错误,因为strdup需要一个有效的 C 字符串。错误消息引用地址0x0表明程序正在取消引用空指针。

现在,passwordFunc("")返回,NULL因为strlen("")是零,零评估为假。

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*同样pw应该返回const 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 回答