为了账号安全,请及时绑定邮箱和手机立即绑定

返回对本地或临时变量的引用

返回对本地或临时变量的引用

C++
动漫人物 2019-07-25 10:03:51
返回对本地或临时变量的引用看下面的代码。我知道它不会返回局部变量的地址,但为什么它仍然有效并将imain()中的变量赋值为'6'?如果从堆栈内存中删除变量,它如何仅返回值?#include <iostream>int& foo(){     int i = 6;     std::cout << &i << std::endl; //Prints the address of i before return     return i;}int main(){     int i = foo();     std::cout << i << std::endl; //Prints the value     std::cout << &i << std::endl; //Prints the address of i after return}
查看完整描述

3 回答

?
HUX布斯

TA贡献1876条经验 获得超6个赞

你真是幸运。从函数返回不会立即擦除刚刚退出的堆栈帧。

顺便说一下,你是怎么证实你有6回来的?表达式std::cout << &i ...打印的是地址i,而不是其值。


查看完整回答
反对 回复 2019-07-25
?
哆啦的时光机

TA贡献1779条经验 获得超6个赞

返回引用或指向局部变量的指针是未定义的行为。未定义的行为意味着,标准将决策留给编译器。这意味着,未定义的行为有时效果很好,有时则不然


查看完整回答
反对 回复 2019-07-25
?
噜噜哒

TA贡献1784条经验 获得超7个赞

地址i永远不会改变main(),但其中包含的值将会改变。您正在引用局部变量并在该引用超出范围之后使用它。(不精确的语言警告)值6在堆栈上。由于在放入堆栈后没有对堆栈执行任何操作,因此6对它的引用仍将包含相同的值。所以,正如其他人所说,你很幸运。

要查看有多幸运,请在调用后尝试运行使用堆栈的代码foo()

#include <iostream>#include <ctime>#include <numeric>int& foo(){
    int i = 6;
    std::cout << &i << " = " << i << std::endl; //Prints the address of i before return
    return i;}long post_foo(int f){
    srand((unsigned)time(0));

    long vals[10] = {0};
    size_t num_vals = sizeof(vals)/sizeof(vals[0]);
    for( size_t i = 0; i < num_vals; ++i )
    {
        int r = (rand()%2)+1;
        vals[i] = (i+f)*r;
    }

    long accum = std::accumulate(vals, &vals[num_vals], 0);
    return accum * 2;}int main(){
    int &i = foo();//  std::cout << "post_foo() = " << post_foo(i) << std::endl;
    std::cout << &i << " = " << i << std::endl; }

当我通过post_foo()注释掉的调用运行它时,6仍然在堆栈上,输出是:

002CF6C8 = 6002CF6C8 = 6

...但是当我没有评论这个电话post_foo()并再次播放时,它6早已不复存在:

001FFD38 = 6post_foo() = 310001FFD38 = 258923464


查看完整回答
反对 回复 2019-07-25
  • 3 回答
  • 0 关注
  • 513 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信