为什么在我销毁列表后我的尾巴仍然指向 Something 而不是指向 NULL
Why is my tail still pointing to Something instead of pointing to NULL after I destroy the list
所以我用 c 语言编写了这段代码,它执行基本的双向链表任务,例如创建列表、插入节点 after/before 给定的当前节点、删除给定的当前节点等等,但是我 运行 当我试图破坏列表时进入这个问题。发生的事情是,当我销毁列表时,它会正确地释放所有节点(至少我在调试器手表中看到的是这样认为),但是当我检查头指针和尾指针是否指向 NULL 时,因为节点没有不再存在,头部指向 NULL,但我的尾巴仍然指向某些东西,我不确定它是列表中未正确释放的节点还是其他东西。
谁能告诉我发生了什么事?这是相关代码;
这是释放所有节点的函数,从而销毁列表
void DListDestruct(DList* list) {
DListNode* tempHead = list->head;;
while (tempHead != NULL) {
tempHead = tempHead->next;
free(list->head);
list->head = tempHead;
}
if (list->tail == NULL) {
list->size = 0;
}
}
//Creation of the structs for the list
typedef struct DListNode_struct {
char *str;
int blankIndex;
int blankLength;
struct DListNode_struct *next;
struct DListNode_struct *prev;
} DListNode;
typedef struct DList_struct {
int size;
DListNode *head;
DListNode *tail;
} DList;
/* This creates a new list and initializes the head/tail */
void DListConstruct(DList* list) {
list->head = NULL;
list->tail = NULL;
list->size = 0;
}
/* inserts newNode after the given currNode */
void DListInsertAfter(DList* list, DListNode* currNode, DListNode* newNode) {
DListNode* sucNode = NULL;
if (list->head == NULL) {
list->head = newNode;
list->tail = newNode;
list->size = list->size++;
}
else if (currNode == list->tail) {
list->tail->next = newNode;
newNode->prev = list->tail;
list->tail = newNode;
list->size = list->size++;
}
else {
sucNode = currNode->next;
newNode->next = sucNode;
newNode->prev = currNode;
currNode->next = newNode;
sucNode->prev = newNode;
list->size = list->size++;
}
}
/* inserts newNode before the given currNode */
void DListInsertBefore(DList* list, DListNode* currNode, DListNode* newNode) {
DListNode* predNode;
if (list->head == NULL) {
list->head = newNode;
list->tail = newNode;
list->size = list->size++;
}
else if (currNode->prev != NULL) {
predNode = currNode->prev;
newNode->next = currNode;
newNode->prev = predNode;
currNode->prev = newNode;
predNode->next = newNode;
list->size = list->size++;
}
else if (currNode->prev == NULL) {
newNode->next = currNode;
currNode->prev = newNode;
list->head = newNode;
list->size = list->size++;
}
}
所以,为什么我销毁List时,使用DListDestroy函数(最上面的第一个),所有节点都被释放,头指针指向NULL,但尾指针仍然指向某个东西?
提前致谢!
那是因为尾部仍然指向你释放的节点的地址,所以现在它指向一些垃圾。
头指向"tempHead"指向的任何地方,到循环结束时它指向空,因为在插入过程中,你把空放在最后一个节点的下一个。
综上所述,tail指向最后一个节点的地址,是垃圾。
head 指向最后一个节点的 next,它是 NULL。
所以我用 c 语言编写了这段代码,它执行基本的双向链表任务,例如创建列表、插入节点 after/before 给定的当前节点、删除给定的当前节点等等,但是我 运行 当我试图破坏列表时进入这个问题。发生的事情是,当我销毁列表时,它会正确地释放所有节点(至少我在调试器手表中看到的是这样认为),但是当我检查头指针和尾指针是否指向 NULL 时,因为节点没有不再存在,头部指向 NULL,但我的尾巴仍然指向某些东西,我不确定它是列表中未正确释放的节点还是其他东西。
谁能告诉我发生了什么事?这是相关代码;
这是释放所有节点的函数,从而销毁列表
void DListDestruct(DList* list) {
DListNode* tempHead = list->head;;
while (tempHead != NULL) {
tempHead = tempHead->next;
free(list->head);
list->head = tempHead;
}
if (list->tail == NULL) {
list->size = 0;
}
}
//Creation of the structs for the list
typedef struct DListNode_struct {
char *str;
int blankIndex;
int blankLength;
struct DListNode_struct *next;
struct DListNode_struct *prev;
} DListNode;
typedef struct DList_struct {
int size;
DListNode *head;
DListNode *tail;
} DList;
/* This creates a new list and initializes the head/tail */
void DListConstruct(DList* list) {
list->head = NULL;
list->tail = NULL;
list->size = 0;
}
/* inserts newNode after the given currNode */
void DListInsertAfter(DList* list, DListNode* currNode, DListNode* newNode) {
DListNode* sucNode = NULL;
if (list->head == NULL) {
list->head = newNode;
list->tail = newNode;
list->size = list->size++;
}
else if (currNode == list->tail) {
list->tail->next = newNode;
newNode->prev = list->tail;
list->tail = newNode;
list->size = list->size++;
}
else {
sucNode = currNode->next;
newNode->next = sucNode;
newNode->prev = currNode;
currNode->next = newNode;
sucNode->prev = newNode;
list->size = list->size++;
}
}
/* inserts newNode before the given currNode */
void DListInsertBefore(DList* list, DListNode* currNode, DListNode* newNode) {
DListNode* predNode;
if (list->head == NULL) {
list->head = newNode;
list->tail = newNode;
list->size = list->size++;
}
else if (currNode->prev != NULL) {
predNode = currNode->prev;
newNode->next = currNode;
newNode->prev = predNode;
currNode->prev = newNode;
predNode->next = newNode;
list->size = list->size++;
}
else if (currNode->prev == NULL) {
newNode->next = currNode;
currNode->prev = newNode;
list->head = newNode;
list->size = list->size++;
}
}
所以,为什么我销毁List时,使用DListDestroy函数(最上面的第一个),所有节点都被释放,头指针指向NULL,但尾指针仍然指向某个东西?
提前致谢!
那是因为尾部仍然指向你释放的节点的地址,所以现在它指向一些垃圾。
头指向"tempHead"指向的任何地方,到循环结束时它指向空,因为在插入过程中,你把空放在最后一个节点的下一个。
综上所述,tail指向最后一个节点的地址,是垃圾。 head 指向最后一个节点的 next,它是 NULL。