0

Scenario is as follows:

typedef struct a {
    void* val;
} a_t;

void fun (void** val)
{
    int a = 5;
    *val = &a;
}

a_t *x;
x = malloc (sizeof *x);
fun (&x->val);

printf ("%d", *((int*)(x->val)));

I would expect, that the x->val is of type void* (when used in printf()). How can I get back that int value I stored into it?

notnull
  • 1,908
  • 3
  • 19
  • 25

2 Answers2

2

The problem is in fun If you expect 5 on STDOUT than this function should look like this:

void fun (void** val)
{
    int *a = malloc(sizeof(int));
    *a = 5;
    *val = a;
}

You should not return pointer to automatic variable because it's allocated on stack and deferred after function executions. To get more info look at this answer

Community
  • 1
  • 1
janisz
  • 6,292
  • 4
  • 37
  • 70
  • If you are OK with the answer, then you should accept it, so your question appears as answered in the feed. :) – gsamaras Nov 15 '14 at 17:09
0

The problem is that the pointer is set to a local variable. So when the function terminates, it's memory will be de-allocated, thus the pointer will be set to garbage (it will become a dangling pointer as Hans suggested).

So if you are lucky, the printf() will print garbage, if not, then it will print 5.


A quick fix would be to add the static keyword to int a, which make it not to be de-allocated when the function gets terminated.

void fun(void** val) {
  static int a = 5;
  *val = &a;
}

However this is not very flexible, because all the instances of fun() will have the same variable a.

Or you could dynamically allocate memory like this:

void fun(void** val) {
  int *a = malloc(sizeof(int));
  *a = 5;
  *val = a;
}

Don't forget to free your memory like this:

  a_t *x;
  x = malloc (sizeof *x);
  fun (&x->val);

  printf ("%d", *((int*)(x->val)));
  free(x->val);  // this has to go first
  free(x);
  return 0;
}
gsamaras
  • 71,951
  • 46
  • 188
  • 305