从函数返回临时对象的引用

5
考虑以下代码 -
#include <iostream>
#include <stdio.h>

const int & retRef() {
    return 6;
}

int main()
{
    const int& k = retRef();
    printf("Value: %d\n", k);
    printf("Address: %p\n", &k);
    printf("Value: %d\n", k);
    return 0;
}

输出结果为 -
Value: 6
Address: 0x7ffd45bf544c
Value: 32692

为什么在打印变量 k 的地址后,其值发生了变化?如果我将行 const int& k = retRef() 替换为 const int& k = 6;,则输出结果符合预期。
这种不同的行为是为什么?谢谢。

稍有挑剔:使用 printf 函数时,应该使用 "%p" 格式来正确输出 void* 类型的指针。需要进行强制类型转换以避免未定义行为。此外,为什么要使用 printf 而不是 std::cout 呢? - Some programmer dude
你试图访问的变量已经被系统从堆栈中清除,因为当函数结束时,它会清除该函数内部的本地变量。 - Denny Kurniawan
3个回答

7
你的代码存在未定义行为;你试图将一个临时int(它是由字面值6构造的)绑定到作为返回值的引用上,但是临时对象会立即被销毁,因此retRef()总是返回一个悬空引用,而k也是悬空的。对其进行任何解引用操作都会导致未定义行为。

每当引用绑定到临时对象或其子对象时,临时对象的生命周期将延长以匹配引用的生命周期,但有以下例外:

  • 绑定到函数返回语句中的函数返回值的临时对象不会被延长:它在返回表达式结束时立即被销毁。这样的函数总是返回一个悬空引用。
另一方面,const int& k = 6;可以正常工作,因为如上所述,临时对象的生命周期被延长到与k相同的生命周期。

1
所以,无论是const int&还是int&&,这都将是未定义的行为,对吗? - kuro
1
@kuro 是的,这无关紧要。 - songyuanyao

4
你正在返回对临时对象的引用,这将导致未定义的行为。一旦函数返回,该对象将不可用。
n4659 - § 15.2:
(6.2) - 函数中的返回语句(9.6.3)中绑定到返回值的临时对象的生命周期不会延长;该临时对象在返回语句的完整表达式结束时被销毁。

0
在函数retRef中,您正在返回对局部变量的引用。 当退出函数时,函数内部的对象将被销毁,所有对它的引用都将变为无效。使用该链接将进一步导致未定义的行为...
const int & retRef()
{
    return 6;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接