user3724090
user3724090

Reputation: 11

Valgrind "Conditional jump or move depends on uninitialised value(s)" errors

I'm very new to C programming (my first question on stackoverflow!) - I was trying to piece together a simple linked list implementation and valgrind starting flagging up errors stating that I was using uninitilised values. Here is my code, with some printing to try to help me see what triggers the issue:

#include <stdio.h>

struct s
{
    int value;
};

struct s *init(int value);

int main(void)
{
    struct s *ptr = init(6);
    printf("In main, ptr->value=%d\n", ptr->value);
    struct s example = *ptr;
    printf("In main, example.value=%d\n", example.value);
    return 0;
}

struct s *init(int valueToSet)
{
    struct s example;
    example.value = valueToSet;
    printf("In init, example.value=%d\n", example.value);

    struct s *ptr = &example;   
    printf("In init, ptr->value=%d\n", ptr->value);

    return ptr;
}

and the output from valgrind:

==8002== Memcheck, a memory error detector
==8002== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==8002== Using Valgrind-3.9.0 and LibVEX; rerun with -h for copyright info
==8002== Command: ./ptr
==8002== 
In init, example.value=6
In init, ptr->value=6
==8002== Invalid read of size 4
==8002==    at 0x8048401: main (ptrproblem.c:13)
==8002==  Address 0xbe8e6088 is just below the stack ptr.  To suppress, use: --workaround-gcc296-bugs=yes
==8002== 
In main, ptr->value=6
==8002== Invalid read of size 4
==8002==    at 0x8048418: main (ptrproblem.c:14)
==8002==  Address 0xbe8e6088 is just below the stack ptr.  To suppress, use: --workaround-gcc296-bugs=yes
==8002== 
In main, example.value=-1097965404
==8002== 
==8002== HEAP SUMMARY:
==8002==     in use at exit: 0 bytes in 0 blocks
==8002==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==8002== 
==8002== All heap blocks were freed -- no leaks are possible
==8002== 
==8002== For counts of detected and suppressed errors, rerun with: -v
==8002== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)

So it looks like when I just use the struct directly, there is no problem, and if I create a pointer to the structure and use it directly, it's fine too. However, when I pass the pointer back to main and use it in the same way, it is incorrect according to valgrind (even though it prints the correct value) and then when I dereference the pointer it is clearly not pointing to the expected memory. I expect I have done something stupid, but I can't see it - can you help me please?

Upvotes: 1

Views: 739

Answers (2)

vmp
vmp

Reputation: 2420

your pointer ptr was assigned to the address of a local variable that will no longer exist after the function finish...

 struct s *init(int valueToSet)
{ 
  struct s *ptr = (struct s*) malloc(sizeof(struct s));
  ptr->value = valueToSet;
  return ptr;
}

you have to add

   #include <stdlib.h> 

at the begining also...

Upvotes: 0

Kerrek SB
Kerrek SB

Reputation: 477660

The value returned by init is not a valid pointer, so it is undefined behaviour to dereference it. This is because it is the address of a local variable, which does no longer exist when the function returns.

Any basic tutorial or text book on C should cover this fundamental topic and how to design code like this. (You need dynamic memory allocations.)

Upvotes: 3

Related Questions