我编写了这个函数来删除单链表的最后一个节点。
问题是,它能够删除除第一个/起始节点之外的所有节点。
此代码段中缺少什么?
请回答我的具体问题。
#include <stdio.h>
#include <stdlib.h>
struct Node
{
char CharContent;
struct Node * NextNodePointer;
};
typedef struct Node Node;
#pragma region Prototypes
Node * CreateNewNode(char ch);
Node * AddNode(Node * start, Node * newNode);
void DeleteTailNode(Node * start);
void PrintAllNodes(const Node * start);
#pragma endregion Comments
main()
{
Node * start = NULL;
Node * newNode = NULL;
start = AddNode(start, CreateNewNode('A'));
start = AddNode(start, CreateNewNode('B'));
start = AddNode(start, CreateNewNode('C'));
start = AddNode(start, CreateNewNode('D'));
PrintAllNodes(start);
DeleteTailNode(start);
PrintAllNodes(start);
DeleteTailNode(start);
PrintAllNodes(start);
DeleteTailNode(start);
PrintAllNodes(start);
DeleteTailNode(start);
PrintAllNodes(start);
DeleteTailNode(start);
PrintAllNodes(start);
getch();
}
#pragma region Node * CreateNewNode(char ch)
Node * CreateNewNode(char ch)
{
struct Node * newNode = (struct Node *) malloc(sizeof(struct Node *));
newNode->CharContent = ch;
newNode->NextNodePointer = NULL;
return newNode;
}
#pragma endregion Comment
#pragma region UnifiedAddNode()
Node * AddNode(Node * start, Node * newNode)
{
Node * copyOfStart = start;
if(start == NULL)
{
return newNode;
}
else
{
while(copyOfStart->NextNodePointer != NULL)
{
copyOfStart = copyOfStart->NextNodePointer;
}
copyOfStart->NextNodePointer = newNode;
return start;
}
}
#pragma endregion Comment
void DeleteTailNode(Node * start)
{
Node * prev = NULL;
Node * current = start;
while(current->NextNodePointer != NULL)
{
prev = current;
current = current->NextNodePointer;
}
free (current);
if (prev != NULL)
{
prev->NextNodePointer = NULL;
}
}
#pragma region PrintAllNodes()
void PrintAllNodes(const Node * start)
{
struct Node * tempRoot = start;
while(tempRoot != NULL)
{
printf("%c, ", tempRoot->CharContent);
tempRoot = tempRoot->NextNodePointer;
}
printf("\n");
}
#pragma endregion Comment
答案 0 :(得分:3)
您没有检测到start为NULL的情况,即列表为空。
在将其设置为NULL之前,您不想释放下一个节点吗?
如果起始节点是最后一个节点prev
在列表遍历完成时将为NULL,但是当发生这种情况时,您要删除(NULL)start->NextNodePointer
,当您想要删除start本身时。
尝试:
void DeleteTailNode(Node *& start)
{
Node * prev = NULL;
Node * current = start;
if (start == NULL)
return;
while(current->NextNodePointer != NULL)
{
prev = current;
current = current->NextNodePointer;
}
if(current != NULL)
free(current);
if(current == start)
start = NULL;
if(prev != NULL)
prev->NextNodePointer = NULL;
}
答案 1 :(得分:2)
内部CreateNewNode()
struct Node * newNode = (struct Node *) malloc(sizeof(struct Node *));
^
|
Ouch!!
将其更改为:struct Node * newNode = (struct Node *) malloc(sizeof(struct Node));
编辑2
测试运行HERE
答案 2 :(得分:1)
您如何理解它是否被删除?正如我所看到的,这里没有任何内容被删除..这是一个100%肯定的内存泄漏...你不在DeleteTailNode中使用免费...你只是让分配的内存无法访问..
编辑:循环后调用自由(当前)。并且不需要检查,如果current为NULL,则删除NULL指针是安全的。