Dangling Pointer in C

雨燕双飞 提交于 2019-11-27 04:54:13

问题


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?


回答1:


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




回答2:


It's because of the way the memory gets allocated.

After calling func and returning a dangling pointer, the part of the stack where num was stored still has the value 100 (which is what you are seeing afterwards). We can reach that conclusion based on the observed behavior.

After the change, it looks like what happens is that the func1 call overwrites the memory location that a points to with the result of the addition inside func1 (the stack space previously used for func is reused now by func1), so that's why you see 200.

Of course, all of this is undefined behavior so while this might be a good philosophical question, answering it doesn't really buy you anything.




回答3:


It's undefined behavior. It could work correctly on your computer right now, 20 minutes from now, might crash in an hour, etc. Once another object takes the same place on the stack as num, you will be doomed!




回答4:


Dangling pointers (pointers to locations that have been disassociated) induce undefined behavior, i.e. anything can happen.

In particular, the memory locations get reused by chance* in func1. The result depends on the stack layout, compiler optimization, architecture, calling conventions and stack security mechanisms.




回答5:


With dangling pointers, the result of a program is undefined. It depends on how the stack and the registers are used. With different compilers, different compiler versions and different optimization settings, you'll get a different behavior.




回答6:


Returning a pointer to a local variable yields undefined behaviour, which means that anything the program does (anything at all) is valid. If you are getting the expected result, that's just dumb luck.




回答7:


Please study functions from basic C. Your concept is flawed...main should be

int main(void)  
{  
    int *a = func();  
    int b;

    b = func1();  
    printf("%d\n%d",*a,func1());  
    return 0;  
}

This will output 100 200



来源:https://stackoverflow.com/questions/5289015/dangling-pointer-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!