C中的悬空指针

pra*_*tri 1 c pointers dangling-pointer

我在C中编写了一个悬挂指针的程序.

#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;
}
Run Code Online (Sandbox Code Playgroud)

即使指针悬空,我输出为100.

我在上面的函数中做了一个改动func1().现在我在编译期间分配值,yz不是像上面的程序那样从标准输入中获取和从中获取值.

我重新定义func1()如下:

int func1(void)
{
    int x,y,z;
    y=100;
    z=100;
    x=y+z;
    return x;
}
Run Code Online (Sandbox Code Playgroud)

现在输出是200.

有人可以解释一下上述两项产出的原因吗?

Eri*_*rik 16

未定义的行为意味着任何事情都可能发生,包括它会像你期望的那样.在这种情况下,您的堆栈变量不会被覆盖.

void func3() {
  int a=0, b=1, c=2;
}
Run Code Online (Sandbox Code Playgroud)

如果你func3()在中间加入一个电话func1,printf你会得到不同的结果.

编辑:在某些平台上实际发生了什么.

int *func(void)
{  
    int num;  
    num = 100;  
    return &num;  
}
Run Code Online (Sandbox Code Playgroud)

为简单起见,假设在调用此函数之前堆栈指针为10,并且堆栈向上增长.

当您调用该函数时,返回地址被压入堆栈(位置10)并且堆栈指针递增到14(是的,非常简化).然后在位置14的堆栈上创建变量num,并且堆栈指针递增到18.

返回时,返回指向地址14的指针 - 从堆栈中弹出返回地址,堆栈指针返回10.

void func2() {
    int y = 1;
}
Run Code Online (Sandbox Code Playgroud)

在这里,同样的事情发生了.返回地址被推到位置,y在位置14处创建,您将1分配给y(写入地址14),返回并将指针堆叠回到位置10.

现在,你的旧点int *func点返回到地址14,对该地址的最后修改是func2的局部变量赋值.所以,你有一个悬空指针(堆栈中位置10以上没有任何内容有效),它指向来自调用的剩余值func2