free函数会把malloc申请的空间释放,但指针仍会指向该区域,但指向的内容发生了变化,这是我经历了血的教训得到的经验
下面上案例,这是一个把带头结点的单链表中结点值为x的结点都删除的程序
#include <stdio.h>
#include <stdlib.h>
/***********************************/
/ 链表实现的头文件,文件名slnklist.h /
/***********************************/
typedef int datatype;
typedef struct link_node{
datatype info;
struct link_node *next;
}node;
/*****************************************************/
/* 函数功能:建立一个空的带头结点的单链表 /
/ 函数参数:空 /
/ 函数返回值:指向node类型变量的指针 /
/ 文件名:hlnklist.c,函数名:init() /
/*************************************************** */
node *init()
{
node head;
head=(node)malloc(sizeof(node));
head->next=NULL;
return head;
}
//
/* 函数功能:输出带头结点的单链表中各个结点的值 /
/ 函数参数:指向node类型变量的指针head /
/ 函数返回值:无 /
/ 文件名:hlnklist.c,函数名:display() */
//
void display(node *head)
{
node *p;
p=head->next;/从第一个(实际)结点开始/
if(!p) printf("\n带头结点的单链表是空的!");
else
{
printf("\n带头结点的单链表各个结点的值为:\n");
while§ { printf("%5d",p->info);p=p->next;}
}
}
//
/* 函数功能:在带头结点的单链表中查找第i个结点地址 /
/ 函数参数:指向node类型变量的指针head /
/ int类型变量i /
/ 函数返回值:指向node类型变量的指针head /
/ 文件名hlnklist.c,函数名find() */
//
node *find(node *head,int i)
{
int j=0;
node *p=head;
if(i<0){printf("\n带头结点的单链表中不存在第%d个结点!",i);return NULL;}
else if(i==0) return p;/此时p指向的是头结点/
while(p&&i!=j)/没有查找完并且还没有找到/
{
p=p->next;j++;/继续向后(左)查找,计数器加1/
}
return p;/返回结果,i=0时,p指示的是头结点/
}
//
/* 函数功能:在带头结点的单链表中第i个结点后插入一个值为x的新结点 /
/ 函数参数:指向node类型变量的指针head /
/ datatype 类型变量x,int型变量i /
/ 函数返回值:指向node类型变量的指针head /
/ 文件名:hlnklist.c,函数名:insert() */
//
node *insert(node *head,datatype x,int i)
{
node *p,q;
q=find(head,i);/查找带头结点的单链表中的第i个结点/
/i=0,表示新结点插入在头结点之后,此时q指向的是头结点/
if(!q)/没有找到/
{printf("\n带头结点的单链表中不存在第%d个结点!不能插入%d!",i,x);return head;}
p=(node)malloc(sizeof(node));/为准备插入的新结点分配空间/
p->info=x;/为新结点设置值x/
p->next=q->next;/插入(1)/
q->next=p;/*插入(2),当i=0时,由于q指向的是头结点,本语句等价于head>next=p */
return head;
}
/本函数的作用是删除表中所有值为x的结点/
node *deleallx(node *head,datatype x)
{
node *pre=head,*p=head;
printf(“请输入要删除的结点值:”);
scanf("%d",&x);
if(head->next==NULL)
{
printf(“单链表为空!”);
return NULL;
}
else
{
while(p->next!=NULL)
{
p=p->next;
if(p->info==x)
{
pre->next=p->next;
free(p); //问题在这,由于把p free掉了,导致p->next没了,所以运行的时候会出问题
} //解决方法是再定义一个临时指针*temp,让他指向p,再到if前面free掉temp,temp置空即可
else
pre=p;
}
return head;
}
}
void main()
{ node *L;
datatype y;
int j,n;
L=init();
/建表/
printf(“请输入带头结点单链表的结点个数:”); scanf("%d",&n);
printf(“请输入带头结点单链表的结点值:”);
for(j=0;j<n;j++)
{scanf("%d",&y); L=insert(L,y,j);}
display(L);
L=deleallx(L,y);
if(L!=NULL)
display(L);
}