Understanding Stack Frames in C

c, gcc, gdb, memory-layout

Solution

The compiler is optimizing away some code in `fun2`.

If you return `&a`, it is optimizing away `int b;`. If you return `&b`, it is optimizing away `int a;`. If you add some dummy computation, you will see that the addresses of returned values will be different.

int * fun2()
{
    int a;
    int b;
    int* p = &a;
    p = &b;
    return p;
}

Change `main` to print the returned values of `fun1` and `fun2`.

int main ()  
{
    int *ptr;
    ptr = fun1();
    printf ("ptr = %p, fun1() called...\n", ptr);
    ptr = fun2();
    printf ("ptr = %p, fun2() called...\n", ptr);
    printf ("*ptr = %d, fun2() called...\n", *ptr);
    return 0;
}

When I run this code, I get the following sample output:

ptr = 0x7ffff98c70ec, fun1() called...
ptr = 0x7ffff98c70e4, fun2() called...
*ptr = 32749, fun2() called...

Problem

I am trying to understand the stack frame in C, so I wrote a simple C code to analyze the stack frame. First of all the fun1() returns an address of a local variable which is initialized to 10 to ptr which leads to a warning but that's ok... If I print the value of *ptr now it prints 10, even that's fine... Next fun2() returns an address of a local variable which is not even initialized and if I try to print the value of *ptr now it prints 10 no matter if i'm returning an address of a or b... To understand what is actually happening here I made use of gdb. Using gdb, I started step by step debugging and when I reached the line "return &a" in fun2(), I tried to print address of b, print &b but it printed Can't take address of "b" which isn't an lvalue. I don't understand when I try to print the address of a, print &a it prints absolutely fine then why not address of b. * Why isn't b an lvalue when a is? ``` # include <stdio.h> int * fun1() { int a = 10; return &a; } int * fun2() { int a; int b; return &a; // return &b; } int main () { int *ptr; ptr = fun1(); ptr = fun2(); printf ("*ptr = %d, fun2() called...\n", *ptr); return 0; } ```

Original source