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
可能效率低下,但我不会打赌。但是,它确实具有非常明显的优势,可以更准确地传达您正在尝试做的事情,而且可读性获胜很少是坏事。
我正在尝试连接两个字符串以便获得文件路径。但是,我在 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
可能效率低下,但我不会打赌。但是,它确实具有非常明显的优势,可以更准确地传达您正在尝试做的事情,而且可读性获胜很少是坏事。