gpt4 book ai didi

c - 返回指向局部变量的指针是UB吗?

转载 作者:行者123 更新时间:2023-12-03 18:52:38 25 4
gpt4 key购买 nike

是的,我很清楚你不应该那样做。如果我们有这个代码:

int *foo() {
int a = 42;
return &a;
}
大多数 C 程序员都知道,这是未定义的行为: Using pointer after free()
int *p = foo();
printf("%d\n", *p);

Just so that future readers don't take this as the truth. Everything below until the question was based on a false assumption from me. It's not UB. It's just bad.


正如一些 C 编码人员所知道的,但比上面的要少,这也是 UB,即使没有取消引用:(试图找到一个关于这个的好问题,但没有找到任何人)
int *p = foo();
printf("%p\n", p); // Should be printf("%p\n", (void*) p);
// Eric P clarified this in his answer, but this missing cast
// is not a part of the primary question
出于同样的原因,这也是 UB,因为发生的情况是指针变得不确定,就像未初始化的变量一样。所谓的悬空指针。
int *p = foo();
int *q = p;
有些人有些惊讶,即使这样也不行:
free(ptr);
if(ptr == NULL) // Just as bad as if ptr is not initialized
问题
我想知道的是,这行是否也调用了 UB:
int *p = foo();
或者甚至这个?
foo();
换句话说,是否 p成为悬空指针,还是分配给悬空指针?
我不知道这是否有任何实际用途,除非对C语言有更深入的了解。一个很好的用例是找出哪些重构是紧急的,哪些可以等待。

最佳答案

C 2018 6.2.4 说“......当它指向(或刚刚过去)的对象到达其生命周期的终点时,指针的值变得不确定。” 3.19.2 告诉我们不确定的值是“未指定的值或陷阱表示”。 3.19.3 告诉我们一个未指定的值是“相关类型的有效值,本文档对在任何情况下选择哪个值没有强加要求”(意味着每次使用时该值可能看起来不同,即使没有对其进行了明显的更改)。
因此在:

int *p = foo();
printf("%p\n", (void *) p); // "(void *)" added to pass correct type for %p.
我们不知道 p 会打印什么值.如果 C 实现没有指针的陷阱表示,则其不确定值不能是陷阱表示,因此不存在未定义的行为。但是,根据 3.19.3,它是一些有效值。
此答案与帖子中的其他问题无关,例如:
int *p = foo();
int *q = p;
分配给 q分配完成后固定的某个值(因此重复打印 q 总是打印相同的值)或分配给 q概念上的“不确定值”(因此重复打印 q 将被允许打印不同的值)。 (无论哪种方式,它都不是未定义的行为,除了陷阱表示的可能性。)

关于c - 返回指向局部变量的指针是UB吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66606248/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com