-1

Let's say I have a struct declared in a temp.h as follows:

/* physical memory */
typedef struct pmem_struct {
 uint32_t val;
} pmem_s, *pmem_p;

And lets say I declare this struct in my temp.c file in the method pmem_p pmem_new() like so:

 pmem_p pmem_new() {
  pmem_s pmems;
  pmem_p pmem = &pmems;
  pmem->val = 0;
  //printf(stderr, "From Mem: %x\n", pmem->val);
  return pmem;
}

Now here is my main.c file:

#include <stdio.h>

#include "temp.h"
#include "gen.h"

int main() {
    pmem_p pmem = pmem_new(); /* create some physical memory */
    fprintf(stderr, "From Mem: %x\n", pmem->val);
......
}

Why is it that this fprintf prints out From Mem: 4019cff4, unless I uncomment the fprintf line in pmem_new(), at which the both correctly print out From Mem:0

  • you return a poiner to a local variable that is destroyed at the end of the function. therefore the returned pointer is invalid. – risingDarkness Sep 28 '12 at 14:51

1 Answers1

4

Because pmem is no longer pointing to a valid memory region after pmem_new() exits. What you are seeing is undefined behavior.

 pmem_p pmem_new() {
  pmem_s pmems;
  pmem_p pmem = &pmems;
  pmem->val = 0;
  //printf(stderr, "From Mem: %x\n", pmem->val);
  return pmem;
}

Here, you allocate pmems on the "stack" inside the scope of the function pmem_new(). With "stack allocation", the memory will become invalid once the program leaves the surrounding scope. Therefore, the pointer to pmems will become a dangling pointer after leaving the function pmem_new().

You could solve it by allocating the memory on the "heap", which the memory won't be destroyed unless you manually do so. In C this is done by the malloc method:

pmem_p pmem_new_correct() {
  pmem_p pmem = malloc(sizeof(*pmem));
  pmem->val = 0;
  return pmem;
}

But you have to remember to free this pointer, otherwise you'll create a memory leak.

int main() {
  pmem_p pmem = pmem_new();
  fprintf(stderr, "From Mem: %x\n", pmem->val);
  ......
  free(pmem);
}

(See also What and where are the stack and heap? for stack vs heap.)

Community
  • 1
  • 1
kennytm
  • 510,854
  • 105
  • 1,084
  • 1,005
  • @user1706394: No, not globals, see KennyTM's update (or create a structure variable (not just a pointer) in main, which is different than a global). – GreenMatt Sep 28 '12 at 16:44