toastedDeli
toastedDeli

Reputation: 580

Why is valgrind reporting an uninitialised value error?

When I run the following code with

valgrind ./test

I get the following error:

==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)

I have added a comment to the line it is complaining about below:

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 is assigned a value by strncpy so why would it be uninitialised by the time it gets to printf?

Upvotes: 0

Views: 69

Answers (2)

user3629249
user3629249

Reputation: 16540

the following proposed code:

  1. corrects several logic errors in the posted code
  2. added missing '#include' statements for needed header files
  3. performs the desired functionality
  4. includes the terminator NUL byte in the call to strncpy() so call to printf() works correctly
  5. cleanly compiles
  6. uses proper signature for main() when parameters are not going to be used
  7. added error checking and handling after call to malloc()

And now the proposed code:

#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
}

and here is the output from a run of the proposed code:

a string

Upvotes: 0

David Schwartz
David Schwartz

Reputation: 182743

Your code never initializes str2[str_len].

In your code, str_len is 8. You need strncpy to copy 9 bytes, the 8 bytes of "a string" and the zero byte that terminates the string. But you only let strncpy copy str_len bytes, that is, 8. So you do not copy the terminating zero byte and printf reads off the end of the data you copied looking for it.

So you have a bug. Instead, pass strncpy the size of the buffer or one more than the strlen(str).

Upvotes: 2

Related Questions