说我有以下两个功能:
1
int * foo()
{
int b=8;
int * temp=&b;
return temp;
}
2
int * foo()
{
int b=8;
return &b;
}
我没有得到第一个警告(例如函数返回本地变量的地址),但我知道这是非法的,因为b
从堆栈中消失,我们是留下指向未定义内存的指针。
那么我什么时候需要注意返回临时值的地址?
答案 0 :(得分:17)
你没有在第一个片段中收到警告的原因是因为你没有(从编译器的角度来看)将地址返回给局部变量。
您将返回int * temp
的值。即使这个变量可能(并且在这个例子中)包含一个值是一个局部变量的地址,编译器也不会上去代码执行堆栈来查看是否是这种情况。
注意:两个片段同样糟糕,即使您的编译器没有警告您前者。不要使用这种方法。
将地址返回给局部变量时应始终小心;作为一项规则,你可以说你从不应该。
static
变量是完全不同的情况,正在this thread中进行讨论。
答案 1 :(得分:1)
我会说你可以返回局部变量,或者更确切地说是指向它由malloc动态分配的IF,在这种情况下,用于存储变量的内存需要在堆栈上但在堆上并且不会被清除或重新 - 在自动局部变量(没有malloc创建)的情况下退出函数后使用,我是对的吗?
答案 2 :(得分:0)
两个例子都同样不正确。我的猜测是你的编译器没有看到危险,因此当你将地址存储在临时变量中时不会发出警告。
答案 3 :(得分:0)
这个问题可能是StackO上讨论最多的问题之一。下面是StackO上类似线程的两个回复,我发现这些回复很有意思,并且可能让我留下了这种去除局部变量的错误做法,尽管我错了(未定义的行为)非常渺茫。
我特别喜欢这个回复。
Here is an example where this bad practice caused some real hardware damage
答案 4 :(得分:-2)
这些都很糟糕,一个好的编译器应该能够检测并警告这两种情况。通过将警告级别设置为最大值(您始终应该这样做),可以获得更好的结果,并打开优化。