C语言中指针和自动存储时间的问题

iyfjxgzm  于 2022-12-17  发布在  其他
关注(0)|答案(1)|浏览(98)

我正在自学指点,对人生有怀疑,看看这个例子:

int* fun(){
    int arr[10];
    for(size_t c = 0;c<10;c++){
        arr[c] = c + 10;
    }
    return arr;
}

int main() {
    int* p;
    p = fun();
    printf("%p",p);
}

这个例子显然会打印一个空地址,因为数组在函数结束后被释放了。为了解决这个问题,我尝试了malloc,它起作用了。
成功之后我尝试了另一种代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>

int* fun(){
    int arr[10];
    for(size_t c = 0;c<10;c++){
        arr[c] = c + 10;
    }
    int* arr2 = arr;
    return arr2;
}

int main() {
    int* p;
    p = fun();
    printf("%p",p);

}

根据我的研究,这个例子应该再次打印一个空地址,但是它和malloc解决方案一样好用。我不明白为什么会发生这种情况。如果int arr[10]被释放,它的指针应该指向null,对吗?

wgmfuz8q

wgmfuz8q1#

这个例子显然将打印一个空地址
不可以。函数返回的地址是 indeterminate,这意味着它没有确定的值。很可能它和arr原来的地址是一样的,但是编译器可以随意打印任何东西,或者把整个东西当作一个“陷阱表示”,这意味着当这种情况发生时,它可能会抛出异常/信号等。
当我在gcc中运行你的代码时,它决定打印“(nil)”输出,而clang认为“明显的”结果应该是0x7ffef0b3c870,程序也可以打印0xDEADBEEF,这也是符合的。
根据我的研究,这个示例应该再次打印空地址
你的研究是建立在错误的结论上的。你看到一辆汽车相撞,它倒着着陆,然后得出结论,当汽车相撞时,它们总是倒着着陆。
在您的两个示例中,返回指针的值都是不确定的。
来源
C17第6.2.4/2节:
如果一个对象在它的生存期之外被引用,那么它的行为是未定义的。当它所指向的对象(或者刚刚过去的对象)到达它的生存期结束时,指针的值就变得不确定了。
C17第3.19.2节:

不确定值

未指定的值或陷阱表示

相关问题