函数参数中的引用会发生什么,如果它在函数返回时被销毁,那么const int *i
仍然是一个有效的指针?
const int* func(const int &x = 5)
{
return &x;
}
int main()
{
const int *i = func();
}
答案 0 :(得分:8)
§12.2/ 5:
“函数调用(5.2.2)中与引用参数的临时绑定一直持续到包含该调用的完整表达式完成为止。”
这意味着当i
被初始化时,它将获得在该点存在的临时对象的地址。但是,只要初始化i
,临时对象就会被销毁,而i
将成为另一个悬空指针。
因此,是的,该函数是有效的 - 但是当您编写它时使用周围的代码,之后添加的任何尝试取消引用i
的代码都会给出未定义的行为。
答案 1 :(得分:3)
仅仅因为指针有值并不意味着它是一个有效的指针。
在这种情况下,它保存的地址曾经是x的地址,很可能地址仍然具有值5,但它不是有效的指针,你不能指望那个值在那里。
答案 2 :(得分:1)
int i
指向一个不安全的内存补丁,它不是一个有效的指针。
答案 3 :(得分:1)
变量“i”仍然是一个指针,但即使读取它指向的值也会给你一个未定义的行为。这就是为什么你永远不应该编写像func这样的函数。
答案 4 :(得分:1)
我认为在设置对x
的调用时,func()
被创建为堆栈中未命名的临时值。此临时将至少存在,直到调用者中的语句结束。所以int* i
完全有效。它只在声明结尾处不再有效 - 这意味着你不能使用它。
标准中有一些关于未命名的临时值被保留,直到最后一次引用它们超出范围,但我不认为它涵盖了这个明确和隐藏的间接。 [很高兴有人告诉我。]
答案 5 :(得分:0)
5是节目数据。它位于数据段中,而不是堆栈或堆中。
因此,对它的指针或引用在程序的持续时间内仍然有效。
答案 6 :(得分:0)
每次调用函数时都会计算默认参数,因此调用func()
实际上是func(5)
,它将临时绑定到const-to-const。然后将该临时的生命周期延长到函数结束并销毁该对象。在此之后指向此对象的任何指针都是无效的并且取消引用它是未定义的行为。