为什么valgrind报告未初始化的值错误?

时间:2019-02-16 21:28:02

标签: c valgrind

当我使用以下代码运行

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时它不会被初始化?

2 个答案:

答案 0 :(得分:2)

您的代码永远不会初始化str2[str_len]

在您的代码中,str_len为8。您需要strncpy复制9个字节,8个字节的“字符串”和零个字节以终止该字符串。但是,您只允许strncpy复制str_len字节,即8字节。因此,您不复制终止的零字节,而printf读出要查找的复制数据的末尾。

所以您有一个错误。相反,传递strncpy的缓冲区大小或比strlen(str)大一个。

答案 1 :(得分:0)

以下建议的代码:

  1. 更正了已发布代码中的一些逻辑错误
  2. 为所需的头文件添加了丢失的“ #include”语句
  3. 执行所需的功能
  4. 在对strncpy()的调用中包含终止符NUL字节,因此对printf()的调用可以正常工作
  5. 干净地编译
  6. 在不使用参数时为main()使用正确的签名
  7. 在调用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