- #include
- using namespace std;
- int * test() {
- // 创建一个int变量
- int a = 1;
- // 返回该变量的地址
- return &a;
- }
- int main() {
- // 声明一个指针
- int * p = 0;
- // 将这个指针指向一个局部变量(函数执行完之后,变量的内存已经被释放掉,而这部分内存已经用于存储其他的值了)
- p = test();
- cout << p << endl;
- // 用原来的地址来取出一个已经不存在的局部变量的数据(由于原内存已被其他数值占据,所以这里将输出意想不到的数据)
- cout << *p << endl;
- // 这时本来是想将原来的a++。但是因为a已不存在,这时对*p指向的进行++操作,其实是修改了其他的数据的值。
- // 这样的操作是非常危险的,因为你不知道该内存这个时候存储的是什么,这样的操作有可能导致系统崩溃。
- (*p)++;
- cout << *p << endl;
- return 0;
- }
程序最终输出:
0xbfaaecb4
12278008
15294453
而不是我们认为的:
0xbfaaecb4
1
2
为了避免这样的问题,我们应该在test函数中,把a变量放到自由存储区域中,而不是堆栈(局部变量)中:
- #include
- using namespace std;
- int * test() {
- // 在自由存储空间中创建一个int变量
- int * a = new int(1);
- // 返回该变量的地址
- return a;
- }
- int main() {
- // 声明一个指针
- int * p = 0;
- // 将这个指针指向一个自由存储空间中的变量(由于该变量在自由存储空间中,因此函数执行完之后,该变量并不会被释放掉)
- p = test();
- cout << p << endl;
- // 该地址指向的数据依然存在
- cout << *p << endl;
- // 可以正常的操作
- (*p)++;
- // 输出正常的结果
- cout << *p << endl;
- // 注意,使用完自由存储区的内存之后,必须要手动释放掉
- delete p;
- // 释放掉内存之后的指针此时还指向原来的内存地址,必须要设置为0(空指针),否则他将成为一个迷途指针,非常危险。
- p = 0;
- return 0;
- }
程序输出:
0x87dd008
1
2