C Strcat valgrind错误

时间:2017-10-12 23:35:25

标签: c string strcat

我正在尝试连接两个字符串,以便获取文件路径。但是,我在valgrind中收到错误

  

条件跳转或移动取决于未初始化的值

我的代码:

/**
 * @brief Concatenate two strings to get file path
 * @param firstP - First string
 * @param secondP - Second string
 * @return Returns the concatenated string
 */
char *getPathDir(char *firstP, char *secondP) {
    char *new_str;
    int stringSize = strlen(firstP)+strlen(secondP)+2;

    if((new_str = malloc(stringSize)) != NULL){
        new_str[0] = '\0';
        strcat(new_str,firstP);
        new_str[strlen(firstP)] = '/';
        strcat(new_str,secondP);
    } else {
        perror("malloc");
        cleanUp();
        exit(EXIT_FAILURE);
    }
    return new_str;
}

1 个答案:

答案 0 :(得分:6)

让我们来看看这些内容:

    new_str[0] = '\0';
    strcat(new_str,firstP);
    new_str[strlen(firstP)] = '/';
    strcat(new_str,secondP);

在写任何东西之前,字符串看起来像这样:

     +---+---+---+---+---+---+---+---+
     | ? | ? | ? | ? | ? | ? | ? | ? |
     +---+---+---+---+---+---+---+---+

在第一行(new_str[0] = '\0';)之后,你有这个:

     +---+---+---+---+---+---+---+---+
     | 0 | ? | ? | ? | ? | ? | ? | ? |
     +---+---+---+---+---+---+---+---+

在第二行(strcat(new_str,firstP);)之后,它看起来像这样:

     +---+---+---+---+---+---+---+---+
     | A | B | C | D | 0 | ? | ? | ? |
     +---+---+---+---+---+---+---+---+

现在,当你执行

行时
    new_str[strlen(firstP)] = '/';

你覆盖了null终结符并得到了这个:

     +---+---+---+---+---+---+---+---+
     | A | B | C | D | / | ? | ? | ? |
     +---+---+---+---+---+---+---+---+

这是一个问题,因为你的字符串不再以空值终止,所以当你下次调用strcat时,程序将开始读取未初始化的内存,寻找空终止符。

如果要将字符串连接在一起,可能更容易使用sprintf,如下所示:

sprintf(new_str, "%s/%s", firstP, secondP);

这更明确地说"写第一个字符串,然后是分隔符,然后是第二个字符串"并将所有空终止符管理卸载到库中。除了strncat之外,库通常很好地处理空终止符。 : - )

sprintf也可能比你正在做的事情稍微快一点。由于overhead of rescanning the strings to find the null terminators,以你提出的方式连续使用大量strcat s可能效率低下,但我不打赌它。但是,它确实具有更明确的优势,可以更准确地传达您正在尝试做的事情,并且可读性获胜很少是坏事。