研究链表空间销毁问题

1.研究链表空间销毁问题

当链表使用完后,需要将链表销毁,那么该如何销毁呢?

void SLTDestroy(SLTNode* phead)//销毁单链表
{
	SLTNode* cur = phead;
   while(cur)
   {
	free(cur);
	cur = cur->next;
	}
}

你看这样对吗?
将cur指向的结点销毁,然后再去找下一个结点,依次循环直到没有结点为止。
但问题是cur都已经销毁了,下面怎么还能使用cur呢?
我们所说的销毁只是将空间的使用权归还给操作系统,使那块区域不再受原本指针控制,那块空间仍然存在,但里面的数据不一定存在。
所以我们在销毁cur以后,就不能再通过cur去找下一个结点了,那这样我们就无法再找到下一个结点了。
研究链表空间销毁问题_第1张图片
然后有人想那我们保存一下cur不就好了吗?

void SLTDestroy(SLTNode* phead)//销毁单链表
{
	SLTNode* cur = phead;
	//用一个指针exist来保存cur
		//然后释放cur再根据exist来找到下一个结点的
	SLTNode* exist = cur;
	while (cur)
{
	free(cur);
	cur = exist->next;
}
}

看似很合理但其实不合理
cur是用来保存phead,而exist是用来保存cur
想通过exist的来找到cur的下一个结点
这个问题和上面是一样的
也就是cur和exist先在都指向同一个结点,然后我们释放这个结点后,cur和
exist都没有用了呀,都不再指向原来的空间,我们保存的不是指向该结点的指针,而是应该保存这个结点啊,这样才能找到这个结点,不然一旦销毁,就找不回来了,还有我们是要找到cur下一个结点的地址哎,我们可以保存指向下一个结点的地址,这样就可以找到第二个结点了
我们应该是保存下一个结点的地址,不要保存自己的地址

void SLTDestroy(SLTNode* phead)//销毁单链表
{
	SLTNode* cur = phead;
//所以我们定义一个next指向cur的下一个结点的地址
	SLTNode* next = cur->next;
	while (cur)
	{
		free(cur);
		cur = next;
	}
}

这样就可以不断的释放结点了。
不过我们是不是忘记什么了?
释放后要将指针置NULL,那我们是不是就直接将cur置为NULL呢?

我们要注意到这里的参数是一级指针,要想真实改变它,需要的是二级指针才行,也就是在这里将cur置为NULL,而在函数外部,cur仍然不是NULL,因为cur是形参,形参的改变不影响实参,不过我们可以在函数外面将实参置NULL,每次调用销毁函数时,都不要忘记手动置空就可以了。
研究链表空间销毁问题_第2张图片

还有一种方法,我们可以通过指针来改变,有的人可能认为cur这不就是指针吗,我们要改变cur这个指针,需要改动的它的指针,也就是二级指针,
将二级指针传过来,然后我们对它解引用访问的就是指向cur的空间了,这时在函数内部将cur置NULL就可以啦。
研究链表空间销毁问题_第3张图片

2.总结: 要改变谁就要传它的指针过去

要改变int 类型的变量,就要传int*过去。
要改变指针,就要传它的指针。
理论就是形参的改变不影响实参

你可能感兴趣的:(数据结构与算法,链表,数据结构,java)