C vs 变量范围中的悬空指针问题

Posted

技术标签:

【中文标题】C vs 变量范围中的悬空指针问题【英文标题】:dangling pointer issue in C vs variable scope 【发布时间】:2021-07-17 04:25:53 【问题描述】:

我知道我们何时将局部变量地址返回给调用者。它变得悬空。为了解决这个问题,我们需要使用静态。这里 x 超出了范围,因此出现了问题。

int *fun()

    // x is local variable and goes out of
    // scope after an execution of fun() is
    // over.
    int x = 5;

    return &x;



int main()

    int *p = fun();
    

    // p points to something which is not
    // valid anymore
    printf("%d", *p);
    return 0;

为什么当我们返回 x 的值而不是它的地址时这不是问题。在这种情况下,x 的值也是局部的,并且在 p 的调用者中,值应该是垃圾,因为局部变量 x 范围结束。

int fun()

    int x=5;
    return x;


main()

    int p;
    p = fun();
    printf("%d", p);

【问题讨论】:

返回给调用者的是x的副本,而不是x本身。 这样的事情最好通过查看汇编代码来理解。您可以使用 -S 选项从 gcc 或 clang 请求程序集。在大多数处理器上,您会看到fun() 将 5 放入寄存器,main 在该寄存器中查找返回值。 '为了解决这个问题,我们需要使用静态'不,你真的不需要。这就是 strtok() 的设计者的想法……无论问题是什么,“静态”都不是答案。 【参考方案1】:

在 C 语言中,函数接收和返回变量的副本。所以你对不存在的局部变量没有问题 - 因为你使用这个变量的值的副本进行操作。

【讨论】:

【参考方案2】:

这里是内存的概念。你的代码内存分为3段,即代码块、堆和堆栈。 每次调用函数时,都会创建函数局部变量并存储在堆栈中,并在函数结束后立即自动删除。 在您的第二个代码中,您已经在 main 函数中声明了变量 p,它带有 fun() 返回的值。函数仅在抛出某个值时终止,在您的代码 p 中,分配了 fun 返回的值在堆栈块中的函数变量被删除之前。 这里我们只是使用 x 变量的副本,它在被编译器删除之前分配给 P。

【讨论】:

以上是关于C vs 变量范围中的悬空指针问题的主要内容,如果未能解决你的问题,请参考以下文章

C语言中的“悬空指针”和“野指针”是什么意思?

c编程中的悬空指针[重复]

这是C ++中的未定义行为从悬空指针调用函数

野指针 悬空指针和悬空引用

通过从本地 C 样式数组返回指针来获取悬空指针

喵呜:C++基础系列:auto关键字(C++11)基于范围的for循环(C++11)指针空值nullptr(C++11)