返回一个本地或临时variables的引用

看下面的代码。 我知道它不会返回局部variables的地址,但为什么它仍然工作,并将variablesi在main()中分配到“6”? 如果从堆栈内存中删除variables,它是如何返回值的?

 #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 } 

你好幸运啊。 从函数返回不会立即清除刚才退出的堆栈框架。

顺便说一句,你怎么确认你有6回? expression式std::cout << &i ...打印std::cout << &i ...的地址,而不是它的值。

必须是你的编译器正在做的事情。

http://www.learncpp.com/cpp-tutorial/74a-returning-values-by-value-reference-and-address/

确认您的示例将从堆栈内存中删除引用。

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

i的地址永远不会在main()改变,但是其中包含的值将会被改变。 你引用了一个局部variables,并在引用超出范围之后使用它。 (不精确的语言警告)值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 = 6 002CF6C8 = 6 

…但是当我对post_foo()的调用取消注释并再次运行时, 6已经过去了:

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

当你的函数通过引用返回一个整数时,它立即被分配给main()中的局部variables'i'。 这意味着分配给foo()的堆栈内存必须足够长才能返回赋值。 虽然这是不好的forms,这通常是有效的。 如果你曾试图保留一个参考

 int &i = foo(); 

它会更有可能失败。