c - C 中的悬空指针

标签 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;
}

即使指针悬空,我也得到了 100 的输出。

我对上面的函数 func1() 做了一个改动。不同于上面程序中从标准输入获取 yz 的值,现在我在编译时分配值。

我重新定义了 func1() 如下:

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

现在输出为 200

谁能解释一下以上两个输出的原因吗?

最佳答案

未定义的行为 意味着任何事情都可能发生,包括它会如您所愿。在这种情况下,您的堆栈变量没有被覆盖。

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

如果在 func1printf 之间包含对 func3() 的调用,您将得到不同的结果。

编辑:一些平台上实际发生了什么。

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

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

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

当您返回时,您返回一个指向地址 14 的指针 - 返回地址从堆栈中弹出,堆栈指针返回到 10。

void func2() {
    int y = 1;
}

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

现在,从 func 返回的旧 int * 指向地址 14,对该地址所做的最后修改是 func2 的局部变量赋值。因此,您有一个悬垂指针(堆栈中位置 10 以上的任何内容均无效)指向调用 func2

时留下的值

关于c - C 中的悬空指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5289015/

相关文章:

c++ - 我应该使用 std::shared 指针来传递指针吗?

c++ - 比较悬空指针是否合法?

c++ - 是否可以在其范围之外访问局部变量的内存?

c - 在 GCC 中使用 Make 时权限被拒绝

c - 使用指针将节点插入二叉树

C 代码在 Linux Debian 中编译失败

c++ - 取消引用地址时是否可以重定向到不同的地址?

c - 访问函数中的双指针结构

C 内存地址和值

c - 在适用于 Windows 和 Linux 的 C 中拖放