C中局部变量的返回地址

C中局部变量的返回地址,c,return,return-value,C,Return,Return Value,假设我有以下两个功能: 1 int * foo() { int b=8; int * temp=&b; return temp; } 2 int * foo() { int b=8; return &b; } 对于第一个,我没有得到任何警告(例如,函数返回局部变量的地址),但我知道这是非法的,因为b从堆栈中消失,我们只剩下一个指向未定义内存的指针 那么什么时候我需要小心返回临时值的地址呢?这两种情况都不好,好的编译器应该能够检测并警告这两种情况。通过将

假设我有以下两个功能:

1

int * foo()
{
  int b=8;
  int * temp=&b;
  return temp;
}
2

int * foo()
{
   int b=8;
   return &b;
}
对于第一个,我没有得到任何警告(例如,函数返回局部变量的地址),但我知道这是非法的,因为
b
从堆栈中消失,我们只剩下一个指向未定义内存的指针


那么什么时候我需要小心返回临时值的地址呢?

这两种情况都不好,好的编译器应该能够检测并警告这两种情况。通过将警告级别设置为最大值(无论如何,您都应该这样做),并启用优化,您可能会获得更好的结果。

这两个示例同样不正确。我的猜测是,您的编译器没有看到危险,因此在将地址存储在临时变量中时不会发出警告。

在第一个代码段中没有收到警告的原因是您没有(从编译器的角度)将地址返回给局部变量

您正在返回
int*temp
的值。即使这个变量可能(在本例中是)包含一个值,该值是一个局部变量的地址,编译器也不会在代码执行堆栈中查看是否存在这种情况

注意:这两个代码段都同样糟糕,即使编译器没有警告您前者。不要使用这种方法


在向局部变量返回地址时,应始终小心;一般来说,你可以说你永远不应该这样做


静态
变量是一个完全不同的情况,我们将在中讨论。

我想说的是,如果本地变量是由malloc动态分配的,您可以返回本地变量或指向本地变量的指针,在这种情况下,用于存储变量的内存应该在堆栈上,但在堆上,并且在退出函数后不会被清除或重新使用,因为它发生在自动局部变量(在没有malloc的情况下创建)的情况下,对吗?

这个问题可能是StackO上讨论最多的问题之一。下面是来自StackO上类似线程的两个回复,我觉得这很有趣,可能让我放弃了这种取消引用局部变量的糟糕做法,尽管我得到错误(未定义行为)的可能性非常小

我特别喜欢这个回答


谢谢!当我在main中打印返回值时,它得到了正确的结果,这实际上意味着它打印垃圾?这意味着你正在调用我们通常称之为的行为,即标准中未指定的行为。具体情况可能是这样的。但也有许多类似的情况涉及到在其他变量(或通过其他函数)之间来回移动地址,这是编译器无法检测到的。此外,优化很少会增加发现此类问题的机会——它只会增加问题产生明显影响的可能性。当然,有些情况编译器无法检测到,但这些特定情况应该很容易检测到。优化之所以有效,是因为它将第一个示例简化为第二个示例。对不起,不是这样。当涉及到编译器的实现质量时,很少有“应该”的地方——这些是基于他们自己的成本/收益分析的供应商决策,这可能不符合开发人员的先入之见。构造示例(例如,可能改变指针的函数调用)也很容易,这意味着您声称的优化可能不可行-这也使得供应商决定是否优化这些东西,而不是给定的。当然,优化不是标准的一部分,因此完全取决于供应商。然而,在本例中,任何不能优化掉不成功的临时代码的编译器都是毫无价值的。另外,如果你读了我的答案,它会说“你可能会得到更好的结果……”祝你有一个愉快的一天。