C++ 返回局部变量的引用与地址

Last updated on September 19, 2021 pm

C++ 返回局部变量的引用与地址

听说 2020 - 1024 = 996?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
using namespace std;
int& refer(int& arg) {
int inter_var = 1024;
return inter_var;
// 返回局部变量的引用
}
int* pointer(const int& arg) {
int var = 0;
return &var;
// 返回指向局部变量的指针
}
int main() {
int number = 996;
// cout << refer(2020); 错误,不是常引用的引用作形参,实参只能是变量(或常量)。
cout << &refer(number) << " " << refer(number)<< endl; // 局部变量被销毁
const int a_const_int = 2020;
// cout << refer(a_const_int); 错误,形参访问限制不能弱于实参。
cout << pointer(2020 - number) << " " << *pointer(number) << endl; // 形参为常引用,实参可以为常量,变量,表达式,数值。
void* v = (void*)pointer(number);
cout << *(int*)v << endl;
return 0;
}

image-20201025001237263

在 Visual Studio 中用 debug 编译,从外部试图访问局部变量时出现了 -858993460。让我们看一下:-858993460 的二进制表示在补码方案下其实是 -858993460 -(-2^31) + 2^31 = 3435973836 的二进制表示,转成 16 进制正是大名鼎鼎的 0xCCCCCCCC 。

image-20201025003653131

以上代码在 TDM-GCC 4.9.2 上编译,发现正常读取。不论哪种编译器,使用 void 指针间接访问均可行,这反映系统并不会在局部变量生命周期结束后便急着将它写入新的值,短时间内内存上的值还是不变的。

image-20201025005648503

不过在 Ubuntu 下用 gcc 9.3.0 编译就不一样了……经 Issues 指点,这可能是 gcc 的一个特性

总之,这种操作应当避免……


C++ 返回局部变量的引用与地址
https://zhaozihanzzh.github.io/2020/10/24/local-variable-pr/
Author
zhaozihanzzh
Posted on
October 24, 2020
Licensed under