今天跟着解学武老师的数据结构教程学单链表,跟着码到了这么一段:
void display(Link* p) { Link* temp = p;//temp指针用来遍历链表 //只要temp指向结点的next值不是NULL,就执行输出语句。 while (temp) { Link* f = temp;//准备释放链表中的结点 printf("%d ", temp->elem); temp = temp->next; free(f); } printf("\n"); }
引用自网站源代码
就跟着学,原封不动地敲到了源代码里。突发奇想既然这个display的时间复杂度是O(n),那么照着这个思路写一个求单链表长度的函数似乎也不是不可以?于是我就照葫芦画瓢:
// 获取链表长度
int getLength(Link* p) {
int length = 0;
Link* temp = p;
while (temp) {
Link* f = temp;
length++;
temp = temp->next;
free(f);
}
printf("链表的长度为:%d\n", length);
return length;
}
在main函数里分别先后运行这两个函数,结果居然中断了!报错了!
这个报错触发原因主要是地址越界等问题。于是就开始排查错误:
①调整先后运行顺序,还是报这个错。
②重复运行display或getLength函数两次,还是报这个错。
③只运行任意一个上述函数,不报错。
所以推测错误应该发生在这两个函数运行之间,就开VCS的断点一句句看,追踪变量然后发现:
怎么p的值执行过程中突然变了?地址没变啊?
一句句排查后发现是free(f)这一句的问题!把f free了之后p也跟着被free了!因为p和f的地址是一样的!
把两个函数中的free语句去掉之后,两个函数就能并列正常运行了。
为什么temp没有跟着被影响?因为执行了temp=temp->next一次,逃过一劫……