菜鸟小乔 发表于 2019-5-30 20:02:32

C清空链表,异常中断“读取访问权限冲突”

void Clear(LinkList* list2)                        //清空链表
{
        Node* node = list2->next;
        Node* nextNode;
        while (node) {                                //当node不为空
                nextNode = node->next;        //先记录当前节点的下个结点,以便释放当前结点内存。
                free(node);
                node = nextNode;
        }
        list2->next = NULL;
        list2->length = 0;
}

这是一段清空链表的C语言代码,

VS运行时中断报错如下:

“引发了异常: 读取访问权限冲突。
node 是 0xFFFFFFFFFFFFFFEF。”

请问这个问题出在哪里,要如何改正呢??

Croper 发表于 2019-5-30 20:24:02

贴完整代码,这一段看不出来问题,

菜鸟小乔 发表于 2019-5-31 11:32:24

本帖最后由 菜鸟小乔 于 2019-5-31 12:39 编辑

Croper 发表于 2019-5-30 20:24
贴完整代码,这一段看不出来问题,

调用其他函数都没问题,就只有调用清空链表函数clear()时有“访问权限冲突”问题。
【.h文件】----定义数据类型,声明函数。
#ifndef linklist_h_include
#define linklist_h_include
#include<stdio.h>
#include<stdlib.h>

#define MAX_SIZE 255
#defineTRUE 1
#defineFALSE 0
//定义一种数据类型
typedef struct {
        int id;
        char* name;
}EleType;

//定义链表节点,包含数据域和指针域
typedef struct Node {
        EleType data;        //数据域
        struct Node* next;        //指针域,指向下个结点
}Node;

//定义 头结点LinkList
//定义链表时示,习惯性定义头结点,以便统一链表节点的插入和删除操作;
//头结点也可以称为首元结点,最后一个结点叫做尾元结点。
typedef struct LinkList {
        Node* next;        //头指针(有头节点,)
        int length;        //链表长度,初始值为0.
}LinkList;

//初始化
void InitLinkList(LinkList* list2, EleType* dataArray, int len);
//插入元素
void Insert(LinkList* list2, int pos, EleType element);

void Print(LinkList* list2);

int IsLinkListEmpty(LinkList*list2);

EleType GetLinkListElement(LinkList* list2, int pos);//查找

EleType DeleteElement(LinkList* list2, int pos);//删除并返回指定位置的节点

void Clear(LinkList*list2);//删除单链表整表,释放内存
#endif

-----------------------------------函数实现------------------------------------------------------------
【.C文件】
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#include"LinkList.h"
///初始化链表////////////////////////////////////////////
void InitLinkList(LinkList* list2, EleType* dataArray, int len)
{
        for (int i = 0; i < len; i++)
        {
                Insert(list2, i + 1, dataArray);
        }
}
//在pos位置插入元素element//////////////////////////////
void Insert(LinkList* list2, int pos, EleType element)
{
        if (pos<1 || pos>list2->length+1)
        {
                printf("错误的下标,插入失败!\n");
                return;
        }
        //step1:创建空结点,并为数据域赋值;即创建一个用来插入的节点node
        Node* node = (Node*)malloc(sizeof(Node));
        node->data = element;
        node->next = NULL;
        //step2:找到要插入的位置的节点;
        if (pos == 1)//插入的是第一个元素
        {
                node->next = list2->next;//给插入节点的后继赋值,
                list2->next = node;//让头节点的next指向插入的这个结点;
                list2->length++;
                printf("if pos==1\n");
                return;
        }
        //不是第一个位置,通过循环找到要插入的节点。
        Node* currNode = list2->next;//cuurNode成为第一个节点
        for (int i = 1; currNode && i < pos - 1;i++)//currNode不为空且
        {
                //目标:循环到currNode->next指向要插入的元素pos位置,
                //currNode就是pos-1的位置,currNode一开始被赋予第一个元素的值,循环到pos-1的位置,循环次数为pos-2。所以条件为i<pos-1
                currNode = currNode->next;//currNode成为下一个节点
        }
        //step3:将结点插入并对接前面的节点
        if (currNode)//currNode不为空
        {
                node->next = currNode->next;//当前结点的next 赋给 插入的结点的next;(与后面连接)
                currNode->next = node;//当前结点的next指向插入的元素(与前面连接)
                list2->length++;
        }       
}
////////////////////////////////
int IsLinkListEmpty(LinkList* list2)
{
        return list2 == 0 ? TRUE : FALSE;
}
///////////////////////////////
EleType GetLinkListElement(LinkList* list2, int pos)//查找
{
        Node*node = list2->next;
        for (int i = 1; node && i < pos; i++)
        {
                node = node->next;
        }
        return node->data;
}
///////////////////////////////
EleType DeleteElement(LinkList* list2, int pos) //删除并返回指定位置的节点
{
        EleType element;                //被删除的元素
        element.id = -999;        //附一个不可能的值,用来判断是否删除成功
        if (pos<1 || pos>list2->length)
        {
                printf("错误的下标,删除失败!\n");
                return;
        }
        Node* node;
        if (pos == 1)//删除第一个节点
        {
                node = list2->next;//把第一个结点赋给node
                if (node)
                {
                        element = node->data;
                        list2->next = node->next;
                        free(node);//释放被删除节点的内存
                        list2->length--;
                }
                return element;
        }
        //1、找到要删除的节点和他的前缀节点
        //2、要删除节点的next复制个前缀的next
        //3、释放
        Node* pre_node=NULL;//前缀节点
        node = list2->next;
        for (int i = 1; node && i < pos ; i++)
        {
                pre_node = node;//前缀结点
                node = node->next;//当前结点
        }
        if (node)
        {
                element = node->data;
                pre_node->next = node->next;
                free(node);
                list2->length--;
        }
}
/////////////////////////////////////////
void Clear(LinkList* list2)//清空链表
{
        Node* node = list2->next;
        Node* nextNode;
        while (node) {        //当node不为空
                nextNode = node->next;//先记录当前节点的下个结点,以便释放当前结点内存。///VS中断报错指向这一行
                free(node);
                node = nextNode;
        }
        list2->next = NULL;
        list2->length = 0;
}
///////////////////////////////////////////
void Print(LinkList* list2)//打印函数
{
        Node* node = list2->next;
        if (!node)
        {
                printf( "链表为空!\n");
                list2->length= 0;
        }
        for (int i = 0; i<list2->length;i++)
        {
                printf("%d\t%s\n", node->data.id, node->data.name);
                node = node->next;
        }
        printf("**************\n");
}

-----------------------main函数-------------------------
#include<malloc.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include"Linklist.h"

//测试数据
EleType dataArray[] = {
        {1,"潇湘妃子"},
        {2,"怡红公子"},
        {3,"蘅 芜 君"},
        {4,"稻香老农"}
};

void test();
/////////////////////
int main()
{
        test();
        return 0;
}
////////////////////
void test()
{
        LinkList list2;
        list2.length = 0;//容易忽略的地方,初始化时长度值为零
        InitLinkList(&list2,dataArray,4);
        //Print(&list2);
       
        Clear(&list2);
}

Croper 发表于 2019-5-31 16:34:53

void test()
{
      LinkList list2;
      list2.length = 0;
      list2.next=NULL; //<<加上
      InitLinkList(&list2,dataArray,4);
      //Print(&list2);
      
      Clear(&list2);
}

菜鸟小乔 发表于 2019-5-31 17:02:47

Croper 发表于 2019-5-31 16:34


多谢大神{:5_109:}
页: [1]
查看完整版本: C清空链表,异常中断“读取访问权限冲突”