我用C写链表
第一个创建的节点的下一个 (node->next
) 是 NULL
最后创建的节点是 HEAD。 (倒序)
我创建了 3 个节点 a, b, c
我想删除 b
节点
这是我的代码:
struct node {
char *name;
void *data;
int size;
struct node *next;
};
typedef struct node Node;
void remove_data(Node *node, char* d_name) {
while (node != NULL) {
// remove data from heap
if (strcmp(node->next->name, d_name) == 0) {
node->next = node->next->next;
printf("remove %s\n", node->next->name);
printf("%s -> %s\n", node->name, node->next->name);
free(node->next);
break;
} else {
node = node->next;
}
}
}
并调用此函数 remove_data(head, d_name);
我预测这个程序打印
remove b
a -> c
但它打印
remove b
b -> b
这是为什么?
答案 0 :(得分:1)
无论如何你的功能都没有意义。
首先它会因为比较而忽略存储在第一个(头)节点中的名称
strcmp(node->next->name, d_name) == 0
^^^^^^^^^^^^^^^^
不能为仅包含一个节点的列表调用该函数。
本次任务结束后
node->next = node->next->next;
指向应删除节点的指针丢失。
还不清楚这些数据成员是什么
void *data;
int size;
表示是否还需要释放指针data
指向的内存。
可以通过以下方式声明和定义该函数,如下所示。函数定义基于您的函数定义。如果需要,那么您还应该插入语句
free( current->data );
之前
free( current );
这里是函数定义。
int remove_data( Node **node, const char *d_name )
{
while ( *node != NULL && strcmp( node->name, d_name ) != 0 )
{
node = &( *node )->next;
}
int success = *node != NULL;
if ( success )
{
Node *current = *node;
*node = ( *node )->next;
free( current );
}
return success;
}
调用函数时,必须将指向头节点的指针传递给函数。
也就是说指向头节点的指针必须通过引用传递。在这种情况下,如果被删除的节点将成为头节点,那么指向头节点的原始指针将被更新。否则函数将处理指向头节点的指针的副本,更改副本不会影响存储在原始指针中的值。