返回对本地或临时变量的引用看下面的代码。我知道它不会返回局部变量的地址,但为什么它仍然有效并将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
,而不是其值。
噜噜哒
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
- 3 回答
- 0 关注
- 513 浏览
添加回答
举报
0/150
提交
取消