当我使用以下代码运行
时valgrind ./test
我收到以下错误:
==8389== Conditional jump or move depends on uninitialised value(s)
==8389== at 0x4E88CC0: vfprintf (vfprintf.c:1632)
==8389== by 0x4E8F898: printf (printf.c:33)
==8389== by 0x40072F: main (test.c:30)
我在下面抱怨的那一行中添加了评论:
int main (int argc, char **argv) {
char str[] = "a string";
int str_len = strlen(str);
char *str2 = malloc(sizeof(char) * (str_len+1)); //source of uninitialised value
strncpy(str2, str, str_len);
printf("%s",str2); //source of error
free(str2);
exit (0);
}
str2由strncpy分配了一个值,那么为什么在到达printf时它不会被初始化?
答案 0 :(得分:2)
您的代码永远不会初始化str2[str_len]
。
在您的代码中,str_len
为8。您需要strncpy
复制9个字节,8个字节的“字符串”和零个字节以终止该字符串。但是,您只允许strncpy
复制str_len
字节,即8字节。因此,您不复制终止的零字节,而printf
读出要查找的复制数据的末尾。
所以您有一个错误。相反,传递strncpy
的缓冲区大小或比strlen(str)
大一个。
答案 1 :(得分:0)
以下建议的代码:
strncpy()
的调用中包含终止符NUL字节,因此对printf()
的调用可以正常工作main()
使用正确的签名malloc()
后添加了错误检查和处理现在是建议的代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main ( void ) // <-- changed
{
char str[] = "a string";
size_t str_len = strlen(str);
char *str2 = malloc( str_len+1 );
if( !str2 ) // <-- added error checking
{
perror( "malloc failed" );
exit( EXIT_FAILURE );
}
// implied else, malloc succesful
strncpy(str2, str, str_len+1); // <-- changed
printf("%s",str2);
free(str2);
// removed 'exit()' statement
}
这是提议的代码运行的输出:
a string