Reputation: 11
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
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
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