Search code examples
cpointersdangling-pointer

Dangling Pointer in C


I wrote a program in C having dangling pointer.

#include<stdio.h>

int *func(void)
{
    int num;
    num = 100;
    return &num;
}

int func1(void)
{
    int x,y,z;
    scanf("%d %d",&y,&z);
    x=y+z;
    return x;
}

int main(void)
{
    int *a = func();
    int b;
    b = func1();
    printf("%d\n",*a);
    return 0;
}

I am getting the output as 100 even though the pointer is dangling.

I made a single change in the above function func1(). Instead of taking the value of y and z from standard input as in above program, now I am assigning the value during compile time.

I redefined the func1() as follows:

int func1(void)
{
    int x,y,z;
    y=100;
    z=100;
    x=y+z;
    return x;
}

Now the output is 200.

Can somebody please explain me the reason for the above two outputs?


Solution

  • Undefined Behavior means anything can happen, including it'll do as you expect. Your stack variables weren't overwritten in this case.

    void func3() {
      int a=0, b=1, c=2;
    }
    

    If you include a call to func3() in between func1 and printf you'll get a different result.

    EDIT: What actually happens on some platforms.

    int *func(void)
    {  
        int num;  
        num = 100;  
        return &num;  
    }
    

    Let's assume, for simplicity, that the stack pointer is 10 before you call this function, and that the stack grows upwards.

    When you call the function, the return address is pushed on stack (at position 10) and the stack pointer is incremented to 14 (yes, very simplified). The variable num is then created on stack at position 14, and the stack pointer is incremented to 18.

    When you return, you return a pointer to address 14 - return address is popped from stack and the stack pointer is back to 10.

    void func2() {
        int y = 1;
    }
    

    Here, the same thing happens. Return address pushed at position, y created at position 14, you assign 1 to y (writes to address 14), you return and stack pointer's back to position 10.

    Now, your old int * returned from func points to address 14, and the last modification made to that address was func2's local variable assignment. So, you have a dangling pointer (nothing above position 10 in stack is valid) that points to a left-over value from the call to func2