C Strcat valgrind 错误

C Strcat valgrind error

我正在尝试连接两个字符串以便获得文件路径。但是,我在 valgrind

中收到错误

Conditional jump or move depends on uninitialised value(s)

我的代码:

/**
 * @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] = '[=10=]';
        strcat(new_str,firstP);
        new_str[strlen(firstP)] = '/';
        strcat(new_str,secondP);
    } else {
        perror("malloc");
        cleanUp();
        exit(EXIT_FAILURE);
    }
    return new_str;
}

让我们看看这些行:

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

在写入任何内容之前,字符串如下所示:

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

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

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

第二行(strcat(new_str,firstP);)之后,是这样的:

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

现在,当您执行该行时

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

你覆盖空终止符并得到这个:

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

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

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

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

这更明确地说 "write the first string, then the separator, then the second string" 并将所有空终止符管理卸载到库中。除了 strncat 之外,库通常可以很好地处理空终止符。 :-)

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