链表的删除操作中得到被删除指针的前一个节点时候的指针异常

Avin 2012-09-18 08:56:43
今天在联系链表的删除操作,该工程包括list.h,list.c,main.c源代码分别如下:list.h
#ifndef _LIST_H
#define _LIST_H

typedef struct _node{

void * data;
struct _node *next;
}NODE;

typedef struct{
NODE *head;
NODE *last;
int length;
}LIST;

LIST * initList();
int insertList(LIST *l,void *data,int size);
NODE * findNodeByKey(LIST *l,void *key,int (*compare)(void *,void *));
NODE * findNode(LIST *l,void *key,int (*compare)(void *,void *),NODE **pre);
int deleteList(LIST *l,void *key,int (*compare)(void *,void *));

#endif


list.c:我单步执行时到红色部分就异常了
#include"list.h"
#include<stdio.h>
NODE * findNode(LIST *l,void *key,int (*compare)(void *,void *),NODE **pre){

NODE *p = NULL;
int s = 0;
if(l == NULL || key == NULL || compare == NULL || pre == NULL){
return NULL;
}
p=l->head;
pre = NULL;
while(p){


if(compare(p->data,key) == 1){
printf("findNode-->find!");
return p;
}
//报错
*pre = p;

p = p->next;
}
return NULL;
}

int deleteList(LIST *l,void *key,int (*compare)(void *,void *)){

NODE *q=NULL,*p=NULL;
/*这是一个很巧妙的编码方式
1.p指向findNode的返回值,也就是查找到的目标节点
2.q指向目标节点的前一个节点,是一个指向指针的指针
3.通过对p的非空判断可以知道是否存在目标节点
4.通过对q的非空判断可以知道目标节点是否是第一个节点
这是一个很灵活的编码方式!
*/
p = findNode(l,key,compare,&q);
if(p == NULL){
//说明目标节点在链表中不存在
return 0;
}
if(q == NULL){
//说明目标节点是第一个节点,前面就是头结点
l->head = p->next;

}else{
//目标节点不是第一个节点,把指针越过删除的节点
q->next = p->next;

}
//如果目标节点是最后一个节点呢
if(p == l->last){
l->last = q;
}
//先释放p的数据域,再释放p
free(p->data);
free(p);
l->length --;

return 1;
}

main.c
在deleteList处开始函数的调用:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include"list.h"

struct STU{
char sno[5];
char sname[10];
int age;
int scroe;
}stu[3]={

{"100","avin",12,299},
{"101","tgip",52,239},
{"102","inca",23,439},
};
//专门比较姓名的函数
int compareByName(void *info,void *key){
//强制类型转换
struct STU *stu = (struct STU *)info;
char *name = (char *)key;
return strcmp(stu->sname,name) == 0 ? 1 : 0;
}
//专门比较学号的函数
int compareBySno(void *info,void *key){
//强制类型转换
struct STU *stu = (struct STU *)info;
char *no = (char *)key;
return strcmp(stu->sno,no) == 0 ? 1 : 0;
}
void main(){
NODE *res = NULL;//查找时候的返回结果
char name[] = "inca";
char no[]="101";
LIST *list = initList();
int i=0;
for(;i<3;i++){
insertList(list,&stu[i],sizeof(stu[i]));
}
res = findNodeByKey(list,name,compareByName);//注意,这里compareByName的名字就代表该函数的地址
if(res == NULL){
printf("not found!\n");
}else{

//强制类型转换
struct STU *st = (struct STU *)res->data;
printf("found! %d\n",st->scroe );
}
/*注意这里的compareBySno
如果携程compareBySno()就表示是方法调用,将会以该方法的返回值传递进入deleteList中。
compareBySno表示将该函数的地址传递进去。
*/
//这里开始删除函数的调用
if(deleteList(list,no,compareBySno) == 1){
printf("delete Success!\n");
}else{
printf("delete failed!\n");
}

}


希望各位帮忙看看,到底是哪错了……
...全文
215 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
mujiok2003 2012-09-20
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 的回复:]
经过几个小时的研究,特来结贴,问题发现了!
问题出在list.c中的第10行
pre = NULL;
应该是
*pre = NULL;
[/Quote]


++
Avin 2012-09-20
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 的回复:]
。。。早知道不看了。
[/Quote]不好意思啦!
Avin 2012-09-20
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 的回复:]
我来帮你顶一下吧,我可以从头到尾好好看了一遍的,连那句“这是一个很巧妙的编程方式”也看了
[/Quote]
多谢了,最近在重新温习数据结构,我看的IT播吧的教程,里边那哥们C语言编码确实很精辟!
Avin 2012-09-19
  • 打赏
  • 举报
回复
顶起啊,难道是分数不够!
Monkey_D_Luffy 2012-09-19
  • 打赏
  • 举报
回复
我来帮你顶一下吧,我可以从头到尾好好看了一遍的,连那句“这是一个很巧妙的编程方式”也看了
冷月清晖 2012-09-19
  • 打赏
  • 举报
回复
。。。早知道不看了。
Avin 2012-09-19
  • 打赏
  • 举报
回复
经过几个小时的研究,特来结贴,问题发现了!
问题出在list.c中的第10行
pre = NULL;
应该是
*pre = NULL;

69,369

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧