详情看代码,有详细注释。特别强调的是当 p 指向一个变量比如 a 时, 我们发现尽管 delete p 了,但是似乎依然可以得到 a 的值, 这其实是错误的,比如 a 最初为 5, delete运算后令 a = 10, 但此时 *p还是等于5.
delete的时候,系统只是将指针指向 的堆空间回收,但是没有将这个指针变量的值赋为NULL,所以delete一个指针后应将其赋为NULL, 不然容易导致野指针的出现。
delete 一个指针变量后一定要将该变量赋为NULL!!!
带指针的结构体比如二叉树等,一定要在构造的时候先把指针全部置为NULL, 否则出现段错误,野指针等不可预知的错误。
#include <bits/stdc++.h>
#define endl "\n"
using namespace std;
int main(){
ios::sync_with_stdio(false);
int m;
while(cin >> m) {
int *p1 = &m;
// int型指针变量p1中的内容(m的地址) p1的地址 p2指向的变量m
cout << " ---> p1 &p1 *p1 " << p1 << " " << &p1 << " " << *p1 << endl;
int *p2 = &m;
cout << " ---> p2 &p2 *p2 " << p2 << " " << &p2 << " " << *p2 << endl;
(*p2)++; // p2指向的变量m+1
cout << " ---> p2 *p2 " << p2 << " " << *p2 << endl;
cout << " ---> p1 *p1 " << p1 << " " << *p1 << endl;
int *p3 = p1;
(*p3)++; // p3指向的变量m+1
cout << " ---> p1 &p1 *p1 " << p1 << " " << &p1 << " " << *p1 << endl;
cout << " ---> p3 &p3 *p3 " << p3 << " " << &p3 << " " << *p3 << endl;
cout << " ---- after delete p3 ----" << endl;
delete p3;
cout << " ---> p1 &p1 *p1 " << p1 << " " << &p1 << " " << *p1 << endl;
// *p3还是m的值,并不是delete后还能获取m的地址及m,delete p3后对m做任何更改*p3输出
// 还是为delete p3前m的值
cout << " ---> p3 &p3 *p3 " << p3 << " " << &p3 << " " << *p3 << endl;
int a = 5;
int *p = new int(a);
// *p = 5
cout << " ---> p &p *p " << p << " " << &p << " " << *p << endl;
cout << " after delete p " << endl;
delete p;
// *p还是等于5
cout << " ---> p &p *p " << p << " " << &p << " " << *p << endl;
cout << " ---- after a = 10 ---- " << endl;
a = 10;
// a的值改变后 *p还是等于5,*p已经不代表a的值了
cout << " ---> p &p *p " << p << " " << &p << " " << *p << endl;
cout << " ---- after make p = &a again ---- " << endl;
p = &a;
// *p又等于10
cout << " ---> &p *p " << &p << " " << *p << endl;
int arr[] = {1, 2, 3};
int *ptr = arr;
// ptr中是arr[0]的地址 &ptr是ptr变量的地址 *ptr是ptr指向的arr[0]的值
cout << " ---> ptr &ptr *ptr " << ptr << " " << &ptr << " " << *ptr << endl;
// 不能有形如 &ptr++ 的形式, 地址值不可做此运算
// ptr指向下一个内存单元,单元大小取决于指针类型, 这里int型则加4(与机器有关),
// 如果是类的对象,那就看该类的一个对象许多多大的内存单元
cout << " ptr++ " << ptr++ << endl;
cout << " ptr " << ptr << endl; // ptr现在指向arr[1]
// (*ptr)++先解指针得到arr[1]再将arr[1]+1
cout << " (*ptr)++ " << (*ptr)++ << endl;
// ptr指向arr[1] arr[1]现在等于3
cout << " ptr *ptr " << ptr << " " << *ptr << endl;
cout << arr[0] << " " << arr[1] << " " << arr[2] << endl;
}
return 0;
}