直接使用运算符的地址与使用指针变量返回局部变量的地址

Posted

技术标签:

【中文标题】直接使用运算符的地址与使用指针变量返回局部变量的地址【英文标题】:Returning address of a local variable directly using address of operator vs using pointer variable 【发布时间】:2019-09-11 06:15:43 【问题描述】:

我知道你永远不应该从函数中返回局部变量的地址。但是在证明这个事实的同时,我遇到了一个问题。考虑以下程序:

int *test()

    int x = 12;
    int *p = &x;
    return p;


int main()

    int *p = test();
    printf("%p",p);
    return 0;

它按预期打印像0061fed0 这样的地址。但是如果我直接使用&返回x的地址,即如果test函数更改如下:

int *test()

    int x = 12;
    return &x;

然后输出变为00000000。那么,你能解释一下这里发生了什么吗?我正在使用与 Windows 10 中的 Code:: Blocks 17.12 IDE 捆绑在一起的 gcc 编译器。

关于重复问题: 建议的重复问题: C - GCC generates wrong instructions when returning local stack address 解释了直接使用运算符地址的行为,但没有解决使用指针变量返回局部变量地址的情况,StoryTeller 的回答中对此进行了解释:“指针的值在它指向(或刚刚过去)的对象到达其生命周期的尽头”。

【问题讨论】:

C - GCC generates wrong instructions when returning local stack address的可能重复 还有:Why does gcc return 0 instead of the address of a stack allocated variable? 未定义的行为是未定义的行为。编译器没有义务生成任何有意义的代码。推测它为什么会产生某种无意义的代码并不是特别有趣。 @Lundin “当指针指向(或刚刚过去)的对象达到其生命周期的尽头时,指针的值变得不确定。”我不知道。这就是我问这个问题的原因。 【参考方案1】:

严格来说,从 C 语言规范的角度来看,这是一个有效的结果。

6.2.4 对象的存储持续时间(强调我的)

2 对象的生命周期是程序执行的一部分 在此期间,保证为其保留存储空间。一个东西 存在,具有恒定地址,并保留其最后存储的值 在其整个生命周期。如果一个对象在其外部被引用 生命周期,行为未定义。 指针的值变成 不确定它指向(或刚刚过去)的对象何时到达 生命周期结束。

因此,无论哪种情况,函数返回的值都是不确定的。您无法预测它将是什么,甚至无法以有意义的方式使用它。使用不确定值的程序具有未定义的行为,任何事情都可能发生。

因此,当您直接返回本地地址时,您的编译器所做的就是返回 null。根据 C 语言本身,它是一个有效值,因为无论如何该对象很快就会死掉。但它的好处是可能会在现代托管实现的早期使您的程序崩溃,并允许您修复错误。

【讨论】:

“当指针指向(或刚刚过去)的对象到达其生命周期的尽头时,指针的值变得不确定。” - 这就是我要找的。谢谢。

以上是关于直接使用运算符的地址与使用指针变量返回局部变量的地址的主要内容,如果未能解决你的问题,请参考以下文章

如何取指针变量的地址?

指针函数不可以返回局部变量地址解决

函数返回局部变量

python中一切皆是对象,对象都是在堆上存放的,一切都是指针

C 语言指针

go强大的垃圾回收机制。