C语言 动态链表的注意点(出现0xcdcdcdcd的情形)
背景
最近学习了一下动态链表,第一次编的时候感觉不太对劲,输出结果后光标一直闪着卡在那里,没有显示那个press any button to continue.于是我仔细跟书本核对了一下,果然发现了错误。
具体分析
先看看我第一次写的代码。(输入多个学号与姓名,组成链表,学号为0表示结束,然后全部输出)
[code]#include<stdio.h> #include<stdlib.h> struct Student { int num; char name[10]; struct Student* ptr; } ; int main() { //head 头指针 p1 p2用于链表建立 p用于输出 struct Student *head=0,*p1,*p2,*p; //n来计算节点数量 int n=0; //先申请第一个节点 返回给p1 p2 p1=p2=(struct Student*)malloc(sizeof(struct Student)); while(1) { scanf("%d",&(p1->num));//输入学号 if(p1->num==0) //输入0 就结束 { p1->ptr=NULL;//最后一个为空指针 break; } scanf("%s",p1->name);//输入姓名 n++; if(n==1) head=p1; else p2->ptr=p1; p2=p1; //p2指向p1 p1=(struct Student*)malloc(sizeof(struct Student));//继续申请 } p=head; do //输出链表 { printf("%d %s\n",p->num,p->name); p=p->ptr; }while(p->ptr!=NULL); return 0; }
接着我们运行程序,输入 12 wang 45 li ,结果如左图:
过了一会儿 ,才终于显示 press any button to continue ,如右图。
虽然程序能正常显示,但显然是出现了一定的问题,于是我们来对代码进行检查。 不难发现其中一个错误在倒数第二行的while条件,即
while(p->ptr!=NULL)
这里应该改为 while(p!=NULL),原因应该很简单,而错误造成的后果等一下会提到。
此时我们再运行一下程序,然而并没有任何改善,并且我们产生了一个更大的疑问,没有修改之前我们应该只能输出第一行数据,可为什么两行都输出了呢?
带着疑问,我进行了单步调试。
调试
调试过程中,12 wang申请的地址为0x007f1780,45 li 申请的地址为0x007f1740 (申请的地址是由大到小的)。
也就是理想状态下,链表应该是这样的:
num | name | ptr | |
head | - | - | 0x007f1780 |
12 | wang | 0x007f1740 | |
45 | li | NULL |
而实际上,调试出来的结果是这样的:
num | name | ptr | |
head | - | - | 0x007f1780 |
12 | wang | 0x007f1740 | |
45 | li | 0xcdcdcdcd | |
0 | - | NULL |
造成第一次时两行都输出的原因无疑是 0xcdcdcdcd的出现,毕竟他也不是空指针,那么它到底是什么呢?
0xcdcdcdcd
查阅资料,我发现0xcdcdcdcd是表示未被初始化的地址,为一个非法地址。所以调试过程中弹出了这个窗口:
既然他是未初始化的(它理应是NULL,但NULL在下一个指针),说明我们程序运行时将NULL的赋值下移了一位。具体地说,就是这一段的p1->ptr=NULL出现了问题:
[code]if(p1->num==0) //输入为0时 { p1->ptr=NULL;//最后一个为空指针 break; }
应该改为 p2->ptr=NULL;修改后结果输出就一切正常了。
释放链表
很多人强调,使用了malloc函数一定要记得free,但是谭浩强的c教材并没有示范如何释放链表,其实释放链表的函数也挺好写的。那就直接上代码吧。
[code]void freeList(struct Student *head)//释放链表 { struct Student *p1,*p2=head; while(p1!=NULL) { p1=p2->ptr; free(p2); p2=p1; } }
感觉核心思想跟链表的建立差不多。把freeList()函数放在printf函数之前,看看它是否真正释放掉,如图:
乱码了,说明链表已经被释放了!
- C语言编写字符串拷贝函数应注意的几个问题
- 【C语言】给一组组数,只有两个数只出现了一次,其他所有数都是成对出现的,找出这两个数。
- c语言编写一段小程序,出现了复制某个文件到一个找不到的路径里边
- 【C语言】一个数组中只有两个数字是出现一次,其他所有数字都出现了两次,找出这两个数字!
- 第03天C语言(17):if的注意点
- linux下的C语言编程注意事项
- C语言中,#include <>和#include ""的区别和注意点
- C语言 编写程序数一下1到100的所有整数中出现多少次数字9
- 【c语言】数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字
- selenium调用Firefox和Chrome需要注意的一些问题,和出现的报错selenium:expected [object undefined] undefined to be a string
- C语言(5) 函数使用需要注意的地方
- C语言strstr()函数:返回字符串中首次出现子串的地址
- 使用C语言需要注意的地方
- 第08天C语言(02):二维数组-注意点
- 【c语言】统计一个数字在排序数组中出现的次数
- C语言 数组中只出现一次的值
- C语言编程需要注意的64位和32机器的区别
- C语言之注意基本类型的范围
- C语言中“命名”需要注意的几点
- C语言(交换两个数组内容,计算分数运算的值,编程计算指定区间整数出现9的次数)