简体   繁体   English

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

[英]Is it UB to return a pointer to local variable?

Yes, I know perfectly well you should not do that.是的,我很清楚你不应该那样做。 If we have this code:如果我们有这个代码:

int *foo() {
    int a = 42;
    return &a;
}

As most C coders know, this is undefined behavior: Using pointer after free()大多数 C 编码人员都知道,这是未定义的行为:在 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.不是UB。 It's just bad.这很糟糕。

As some C coders know, but less than for above, that this also is UB, even though no dereferencing is done: (Was trying to find a good question about this, but did not find anyone)正如一些 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

And for the same reason, also this is UB, because what happens, is that the pointer become indeterminate, just like an uninitialized variable.出于同样的原因,这也是 UB,因为发生的情况是指针变得不确定,就像未初始化的变量一样。 A so called dangling pointer.所谓的悬空指针。

int *p = foo();
int *q = p;

And somewhat surprising to some, even this is not ok:有些人有些惊讶,即使这样也不行:

free(ptr);
if(ptr == NULL) // Just as bad as if ptr is not initialized

The question问题

What I do wonder, is if also this single line invokes UB:我想知道的是,这一行是否也调用了 UB:

int *p = foo();

Or maybe even this?或者甚至可能是这个?

foo();

In other words, does p become a dangling pointer, or does it get assigned to a dangling pointer?换句话说, p成为一个悬空指针,还是被分配给一个悬空指针?

I don't know if there's any practical use for this, except deeper understanding for the C language.我不知道这是否有任何实际用途,除了对 C 语言有更深入的了解。 Well one good use case would be to figure out which refactorings that are urgent and which can wait.一个好的用例是找出哪些重构是紧急的,哪些可以等待。

C 2018 6.2.4 says “… The value of a pointer becomes indeterminate when the object it points to (or just past) reaches the end of its lifetime.” C 2018 6.2.4 说“......当指针指向(或刚刚过去)的 object 达到其生命周期的终点时,指针的值变得不确定。” 3.19.2 tells us an indeterminate value is “either an unspecified value or a trap representation.” 3.19.2 告诉我们不确定值是“未指定的值或陷阱表示”。 3.19.3 tells us an unspecified value is a “valid value of the relevant type where this document imposes no requirements on which value is chosen in any instance” (meaning the value can appear to be different each time we use it, even if no apparent changes are made to it). 3.19.3 告诉我们未指定的值是“相关类型的有效值,其中本文档对在任何情况下选择哪个值没有要求”(意味着每次使用时该值看起来都不同,即使没有对其进行了明显的更改)。

Thus in:因此在:

int *p = foo();
printf("%p\n", (void *) p); // "(void *)" added to pass correct type for %p.

We do not know what value will be printed for p .我们不知道将为p打印什么值。 If the C implementation has no trap representations for pointers, then its indeterminate value cannot be a trap representation, so there is no undefined behavior.如果 C 实现没有指针的陷阱表示,则其不确定值不能是陷阱表示,因此没有未定义的行为。 However, it is, per 3.19.3, some valid value.但是,根据 3.19.3,它是一些有效值。

This answer does not speak to other questions in the post, such as whether:此答案不涉及帖子中的其他问题,例如是否:

int *p = foo();
int *q = p;

assigns to q some value that is fixed once the assignment is done (thus printing q repeatedly always prints the same value) or assigns to q the notional “indeterminate value” (thus printing q repeatedly would be allowed to print different values).分配给q一些一旦完成分配就固定的值(因此重复打印q总是打印相同的值)或分配给q名义上的“不确定值”(因此允许重复打印q打印不同的值)。 (Either way, it is not undefined behavior, except for the possibility of trap representations.) (无论哪种方式,它都不是未定义的行为,除了陷阱表示的可能性。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 我无法返回指向局部变量的指针,但我可以返回指向 c 中的局部结构数据的指针? - I cannot return pointer to local variable, but I can return pointer to data of local struct in c? 在同一个函数中,UB是否可以通过间接访问 - 一个不在范围内的局部变量? - Within the same function, is it UB to access—through indirection—a local variable not in scope? 将指针包装在结构中时返回指向局部变量的指针是否仍然是未定义的行为 - Is it still undefined behaviour to return a pointer to a local variable when it is wrapped in a struct 指向局部变量的指针仍然存在 - Pointer to a local variable survives 为什么要使用局部变量指针? - Why local variable pointer? 将指针转换为空指针并写入它是 UB 吗? - Is it UB to cast a pointer to a void pointer and write to it? 为什么ptr不会变成悬挂指针,因为当返回function后存储局部变量地址的返回指针被销毁? - Why ptr not becomes Dangling pointer because when return pointer who store the address of local variable get destroy after return function? 释放函数本地的指针并返回该指针 - Free a pointer local to a function and return the pointer 返回指向静态局部变量的指针 - Returning pointer to static local variable 被 C 中的指针和局部变量混淆 - confused by pointer and local variable in C
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM