我正在努力编写一个删除包含链接列表中字符串的节点的方法。这就是我所拥有的。
struct node {
char name[128];
struct node *next;
};
struct node *list_delete(const char *name, struct node *list) {
if (list->next == NULL && strcmp(name, head_name) == 0) {
struct node *temp = list;
list = list->next;
free(temp);
return list;
}
struct node *head = malloc(sizeof(struct node));
head = list;
while (head->next != NULL) {
if (strcmp(name, head->name) == 0) {
struct node *temp = head;
head = head->next;
free(temp);
break;
}
head = head->next;
}
return list;
}
当我运行时,我收到错误:
双重免费或腐败(!prev)
我想看看我是不是在我不应该的地方解放,但我想我已经拥有了。我也是C的新手,所以我还在学习。
答案 0 :(得分:0)
如果没有看到调用它的代码,看起来你可能会遇到上一次返回return list;
的问题。如果第一项是免费的,那么你将返回指向最近释放的内存的指针可能会再次释放它。
答案 1 :(得分:0)
您拥有的是前向链接列表。因此,在删除时,您需要在删除目标之前直接维护指向项目的指针。由于你的删除函数返回一个指针,我将假设这会返回新的头部(如果目标元素不是头部,则返回当前的头部。)
我应该指出,我的下面的例子有一点需要注意,它只删除第一个匹配项并且不处理具有相同名称的多个元素。如果您需要处理,您需要做的就是在while(1)
中包含现有的return head;
循环,并将最后2 continue;
个语句替换为struct node *list_delete(const char *name, struct node *list) {
struct node* prev = NULL;
struct node* head = list;
while (list) {
if (!strcmp(list->name, name))
break;
prev = list;
list = list->next;
}
if (!list)
return head; //not found, no change.
if (!prev) { //element to destroy is first one
head = list->next;
free(list);
return head;
}
prev->next = list->next; //make previous skip target
free(list); //destroy found element
return head; //head unchanged
}
JFrame
答案 2 :(得分:0)
我个人觉得最好有几个指针来跟踪列表遍历。
struct node *list_delete(const char *name, struct node *list) {
struct node *cur = NULL, *nxt = NULL;
if( list ) { /** Valid List **/
cur = list;
nxt = list->next;
while( nxt ) { /** Next Pointer Exists **/
if ( strcmp( name, nxt->name ) == 0 ) { /** and Next node is what we are looking for **/
cur->next = nxt->next; /** Skip Next Node **/
nxt->next = NULL; /** Detach It **/
free(nxt); /** Free it **/
return list; /** Return list **/
}
nxt = nxt->next; /** Go on further **/
cur = cur->next;
}
if ( strcmp( name, cur->name ) == 0 ) { /** will handle single node case **/
free( cur );
return NULL;
}
}
return NULL;
}
答案 3 :(得分:0)
对代码进行一些更改。请记住,if-else分支中不应该遗漏。
在我的NetBeans环境中通过
首先,请不要直接编辑头节点!
因为这在练习中确实是一种糟糕的方式。
此外,我认为typedef
是您想要定义结构时的更好选择。
typedef struct node {
char name[128];
struct node *next;
}Node;
Node *deleteNode(const char *name, Node *head) {
/*
* Give one recommendation:You'd better use
* a temp pointer instead of using the input
* parameter directly.There is no rule for
* this, but I think it's a good code manner.
*/
Node *ptr = head;
Node *nxt;
if(ptr == NULL)
return head;
/*
* If the head node meet the requirement.
*/
else if(strcmp(ptr->name,name) == 0){
head = head->next;
free(ptr);
}
else{
/*
* Search from the second Node in the List.
*/
while(ptr->next != NULL){
/*
* Using a temp Node pointer.
* So you could free the mateched Node.
*/
nxt = ptr->next;
if(strcmp(nxt->name,name) == 0){
ptr->next = nxt->next;
free(nxt);
break;
}
else{
ptr = ptr->next;
continue;
}
}
return head;
}
}