C语言 在链表删除函数中,是否有必要使用 free 来删除节点?



我看到了这个节点删除功能,并将其与我的书进行了比较。它(几乎(完全不同,我想后者对学习有用......?但是我无法理解如果只需要向前移动指针,为什么甚至使用免费。也许我错过了什么。

作为参考,这是我书中的删除节点函数:

char delete(ListNodePtr *sPtr, char value){
if(value == (*sPtr)->data){
ListNodePtr tempPtr = *sPtr; 
*sPtr = (*sPtr)->nextPtr; 
free(tempPtr); 
return value;
}
else{
ListNodePtr previousPtr = *sPtr;
ListNodePtr currentPtr = (*sPtr)->nextPtr;
while(currentPtr != NULL && currentPtr->data != value){
previousPtr = currentPtr; 
currentPtr = currentPtr->nextPtr;
}

if(currentPtr != NULL){
ListNodePtr tempPtr = currentPtr;
previousPtr->nextPtr = currentPtr->nextPtr;
free(tempPtr);
return value;
}
}
return '';
}

我还尝试完全删除 temp 变量和 free 调用,并且该函数仍然(显然(有效,因为在打印函数中不打印"已删除"值。

一直在查看链表上的其他来源,其中许多都显示了免费功能的用法,奇怪。

Linus描述了Linux内核中使用的列表。有趣的是,这些是侵入性列表,这意味着列表管理代码不负责释放节点,因为列表拥有它们。

此外,该站点上的代码不是用于删除节点的完整功能,而只是用于取消链接的行。

不过,您自己的列表可能是使用malloc()-ed 内存的拥有列表,对吧?

对于初学者来说,代码非常非常糟糕。首先是有重复的代码。其次,功能过于复杂。

它可以写得更简单。例如

char delete( ListNodePtr *sPtr, char value )
{
while ( *sPtr != NULL && ( *sPtr )->data != value )
{
sPtr = &( *sPtr )->nextPtr;
}
char result = *sPtr == NULL ? '' : value;
if ( *sPtr != NULL )
{
ListNodePtr tempPtr = *sPtr;
*sPtr = ( *sPtr )->nextPtr;
free( tempPtr );
}
return result;
} 

此外,将 typedef 用于指针也是一个坏主意,就像在您的程序中一样ListNodePtr显然是这样的 typedef。例如,此类型说明符

const ListNodePtr

并不意味着ListNodePtr类型的指针指向的数据是常量数据,并且不能更改。这意味着指针本身是常量。

考虑以下演示程序

#include <stdio.h>
typedef int * IntPtr;
int main(void) 
{
int x = 10;
const IntPtr p = &x;
*p = 20;
printf( "x = %dn", x );
return 0;
}

它的输出是

x = 20

至于你的问题

在链表删除函数中,是否有必要使用 free to 删除节点?

然后,退出函数后,对已删除节点的引用将丢失,如果不删除节点,则只要节点是动态分配的,就会发生内存泄漏。

如果你不使用free,那么你会导致内存泄漏。如果您在不释放内存的情况下移动指针,则会导致内存泄漏。

最新更新