Почему valgrind сообщает об ошибке неинициализированного значения? - PullRequest
0 голосов
/ 17 февраля 2019

Когда я запускаю следующий код с

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 голосов
/ 18 февраля 2019

следующий предложенный код:

  1. исправляет несколько логических ошибок в опубликованном коде
  2. добавлены пропущенные операторы "#include" для необходимых заголовочных файлов
  3. выполняеттребуемая функциональность
  4. включает байт NUL-терминатора в вызове strncpy(), поэтому вызов 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
0 голосов
/ 17 февраля 2019

Ваш код никогда не инициализируется str2[str_len].

В вашем коде str_len равно 8. Вам нужно strncpy, чтобы скопировать 9 байтов, 8 байтов "строки" и нулевой байт, которыйзавершает строку.Но вы позволяете только strncpy копировать str_len байтов, то есть 8. Таким образом, вы не копируете завершающий нулевой байт, а printf считывает конец скопированных данных, ища его.

Итак, у вас есть ошибка.Вместо этого передайте strncpy размер буфера или на один больше strlen(str).

...