在本地调试树形结构时,常常需要释放一棵树里全部指针所占的空间,这一步不需要了解树的具体结构;
我认为最简单通用的方法就是用广度优先周游的方法将树中的非空节点依次删除;
但这里由于指针操作的复杂性,写出来的代码常常出现以下两种情况:1.传递的是指针的值而非指针本身,从而没有释放想释放的空间 2.删除过程中出现了runtime error,即访问了不能访问的空间(如悬垂指针or 系统自留地址)
为了避免出现指针使用的混淆,首先要弄清楚指针的地址,指针的内容和指针指向之间的关系:
为此,我写了下面这段代码来测试:
#include<iostream>
#include<cstdio>
#include<string>
#include<string.h>
#include<cstring>
using namespace std;
int main(){
int *digit = new int;
*digit = 5;
int *sub;
sub = digit;
cout << "digit address:" << &digit << endl;
cout << "digit content:" << digit << endl;
cout << "digit pointer:" << *digit << endl << endl;
cout << "sub address:" << &sub << endl;
cout << "sub content:" << sub << endl;
cout << "sub pointer:" << *sub << endl << endl;
delete sub;
cout << "digit address:" << &digit << endl;
cout << "digit content:" << digit << endl;
cout << "digit pointer:" << *digit << endl << endl;
return 0;
}
结果(codeblocks,mingw)
digit address:0x28fecc
digit content:0x3511a0
digit pointer:5
sub address:0x28fec8
sub content:0x3511a0
sub pointer:5
digit address:0x28fecc
digit content:0x3511a0
digit pointer:3477600
sub address:0x28fec8
sub content:0x3511a0
sub pointer:3477600
可以看出13行将digit的内容(0xad11a0)赋值给了sub,即现在digit和sub的值是相同的,所以解引用之后的值相同(5),但是地址是不同的。因为地址是变量的特征,由系统自动分配,而非用户决定。
21行delete sub之后,即释放了指针的空间,尽管sub和digit指针的内容不变,但是指针对应的int变量已经被撤销,即相应的堆空间可以被重新分配;
同时这里的digit就是通常所说的悬垂指针,
在编写程序的过程中,要避免悬垂指针的干扰,就要在delete之后及时将指针置为NULL,避免出现莫名其妙的错误(在这里,如果delete sub之后继续使用*digit,虽然不会出现
segmentation fault,但是数据已经不是我们想要的了)
在弄清楚指针的值和指向的内容之间的关系后,我又尝试着将指针传递给一个函数
#include<iostream>
#include<cstdio>
#include<string>
#include<string.h>
#include<cstring>
using namespace std;
void Delete(int*);
int main(){
int *digit = new int;
*digit = 5;
cout << "digit content " << digit << endl << endl;
Delete(digit);
cout << "after change\n";
cout << "digit content" << digit << endl << endl;
cout << "digit pointer" << *digit << endl << endl;
return 0;
}
void Delete (int *pint){
delete pint;
cout << "pint content " << pint << endl << endl;
pint = NULL;
}
digit content 0x3b1118
pint content 0x3b1118
after change
digit content0x3b1118
digit pointer3871088
可以看出在Delete函数作用之后,digit指向的空间已经被释放,但是对参数pint的修改没有引起digit值的修改,这和传递其它类型的参数只会不会改变传入的参数是一个道理,
但是实际上申请的空间已经被释放了