读书人

链表的删除操作中得到被删除指针的前一

发布时间: 2012-10-19 16:53:37 作者: rapoo

链表的删除操作中得到被删除指针的前一个节点时候的指针异常
今天在联系链表的删除操作,该工程包括list.h,list.c,main.c源代码分别如下:list.h

C/C++ code
#ifndef _LIST_H#define _LIST_Htypedef 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:我单步执行时到红色部分就异常了
C/C++ code
#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;        }        [color=#FF0000]//报错        *pre = p;[/color]        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处开始函数的调用:
C/C++ code
#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表示将该函数的地址传递进去。    */       //这里开始删除函数的调用    [color=#FF0000]if(deleteList(list,no,compareBySno) == 1){        printf("delete Success!\n");    }else{        printf("delete failed!\n");    }[/color]}


希望各位帮忙看看,到底是哪错了……


[解决办法]
。。。早知道不看了。
------解决方案--------------------


我来帮你顶一下吧,我可以从头到尾好好看了一遍的,连那句“这是一个很巧妙的编程方式”也看了

读书人网 >C语言

热点推荐