为什么 valgrind 报告未初始化值错误?
Why is valgrind reporting an uninitialised value error?
当我运行下面的代码加上
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 时未初始化?
您的代码从未初始化 str2[str_len]
。
在您的代码中,str_len
是 8。您需要 strncpy
复制 9 个字节,"a string" 的 8 个字节和终止字符串的零字节。但是你只让 strncpy
复制 str_len
个字节,即 8 个字节。所以你不复制终止零字节并且 printf
读取你复制的数据的末尾寻找它。
所以你有一个错误。相反,传递 strncpy
缓冲区的大小或比 strlen(str)
.
多一个
以下建议代码:
- 更正了发布代码中的几个逻辑错误
- 为所需的头文件添加了缺少的“#include”语句
- 执行所需的功能
- 在对
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
当我运行下面的代码加上
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 时未初始化?
您的代码从未初始化 str2[str_len]
。
在您的代码中,str_len
是 8。您需要 strncpy
复制 9 个字节,"a string" 的 8 个字节和终止字符串的零字节。但是你只让 strncpy
复制 str_len
个字节,即 8 个字节。所以你不复制终止零字节并且 printf
读取你复制的数据的末尾寻找它。
所以你有一个错误。相反,传递 strncpy
缓冲区的大小或比 strlen(str)
.
以下建议代码:
- 更正了发布代码中的几个逻辑错误
- 为所需的头文件添加了缺少的“#include”语句
- 执行所需的功能
- 在对
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