Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding Stack Frames in C

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;
}
like image 247
Adarsh Avatar asked Apr 25 '14 05:04

Adarsh


1 Answers

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...
like image 69
R Sahu Avatar answered Nov 07 '22 03:11

R Sahu