strdup()导致EXC_BAD_ACCESS

时间:2012-05-12 20:34:19

标签: c exc-bad-access

我有以下代码:

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)崩溃。

有关正在发生的事情以及如何解决问题的任何建议?提前谢谢。

2 个答案:

答案 0 :(得分:4)

passwordFunc("")正在返回NULL。当您将其传递给strdup时,会出现分段错误,因为strdup需要有效的C字符串。错误消息引用地址0x0表示程序正在取消引用空指针。

现在,passwordFunc("")返回NULL,因为strlen("")为零,零值为false。

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*。您的编译器可能会警告您这一点,您应该留意这些警告。

答案 1 :(得分: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(""));
    }
}