如何在链表的c代码中修复此错误?
我在Xcode上收到一个错误,当我在c中为一个单链表使用delete函数时,我不知道为什么。我收到的错误是 “malloc:*对象0x7FFEEFBF5D8的错误:未分配要释放的指针*在malloc\u error\u break中设置断点以进行调试”如何在链表的c代码中修复此错误?,c,linked-list,C,Linked List,我在Xcode上收到一个错误,当我在c中为一个单链表使用delete函数时,我不知道为什么。我收到的错误是 “malloc:*对象0x7FFEEFBF5D8的错误:未分配要释放的指针*在malloc\u error\u break中设置断点以进行调试” 有许多事情是不清楚或不必要的 为什么要释放自由(列表)列表是双指针,如果您释放此链接列表的头指针,它将松动。删除操作后,如果需要,如何再次打印/访问列表 list是保存链接的headpointer,您没有在main()或调用函数中为list分配
有许多事情是不清楚或不必要的
- 为什么要释放
自由(列表)
是双指针,如果您释放此链接列表的列表
,它将松动。删除操作后,如果需要,如何再次打印/访问列表头指针
是保存链接的list
,您没有在headpointer
或调用函数中为list分配任何内存,因此无法释放它。这就是错误的原因main()
释放
,那么首先您应该执行释放(*list)
,然后执行释放(list)
- 从您的代码段
free(list); /* list is freed here */ *list=temp; /* How will you access again *list */
if
块应该是
if (*list != NULL) {
node * temp= *list;
temp = temp->next; /* temp holds 2nd node address & you need that only */
}
首先,您的问题非常不清楚,下次请发布所有必要的代码,并在几行中解释函数的用途 我猜您要做的是根据参数
data
的值从链表中删除特定项
从网站:
"
删除特定项目
要从列表中删除特定项,无论是从列表开头的索引还是从其值,我们都需要检查所有项,不断向前看,以确定是否在要删除的项之前到达了节点。这是因为我们还需要将位置更改为前一个节点指向的位置
以下是算法:
祝你好运你的代码有错误的逻辑和明显的错误。 一旦列表被释放,您就无权再次访问它
free(list);
*list=temp;
管理链表并不困难,但需要注意细节
- 删除列表中的节点时,您有责任连接这些节点
- 如果删除头部,则有责任移动头部
- 如果头部是您要查找的节点,并且这是列表中唯一一个删除后的节点,则必须将该节点标记为
NULL
struct node*find(struct node*start,int data)
函数查找符合条件的节点,并使用delete
将其删除。所有边缘案件都已得到处理
#include <stdio.h>
#include <stdlib.h>
// Basic simple single list implementation to illustrate
// a proper deletion of the node which has a specfic data value.
// Node in List
typedef struct node {
int data;
struct node* next; // pointer to next node
}node;
// List structure
typedef struct list {
node* head; // The entry point into a linked list. If the list is empty then the head is a null reference.
} list;
// Create list
list* list_create()
{
list* new_list = malloc(sizeof(list));
if(new_list == NULL)
return NULL; // protection
new_list->head = NULL; // If the list is empty then the head is a null reference. no elements in the list
return new_list; // return created new list
}
// returns newly created node
node* node_new(int data)
{
node* new_node = malloc(sizeof(node)); // allocate memory for the node
if (new_node == NULL)
return NULL; // protection
new_node->data = data; // remember the data
new_node->next = NULL; // no next node
return new_node; // return new created node
}
// The method creates a node and prepends it at the beginning of the list.
//
// Frequently used names for this method:
//
// insert at head
// add first
// prepend
//
// returns new head or NULL on failer
node* prepend_node(list* in_list, node* new_node)
{
// Add item to the front of the in_list, return pointer to the prepended node (head)
if(in_list == NULL)
return NULL;
if(new_node == NULL) // problem, not enough memory
return NULL; // in_list->head has not changed
/*
new_node
|*| --> NULL
next
*/
if(in_list->head == NULL) // if list is empty
{
in_list->head = new_node; // the new_node becomes a head
}
else // list already have a head node
{
/*
|2|-->|1|-->NULL
^
|
*
head (2) (list pointer)
*/
new_node->next = in_list->head; // now, the new node next pointer points to the node pointed by the list head, see below:
/*
new_node
|3|--> |2|-->|1|-->NULL
^
|
*
head (list pointer)
*/
in_list->head = new_node; // the list head has to move to new_node ( a new prepanded node)
/*
new_node
|3|--> |2|-->|1|-->NULL
^
|
*
head (3) (list pointer)
*/
}
return in_list->head; // we are returning pinter to new_node
}
// Print out list
void print_list(list* in_list)
{
node* node;
if (in_list == NULL)
{
return;
}
if (in_list->head == NULL)
{
printf("List is empty!\n");
return;
}
printf("List: ");
node = in_list->head;
while(node != NULL)
{
printf(" %d", node->data);
node = node->next;
}
printf("\n");
}
struct node *find(struct node *start, int data) // find p to be removed
{
node* node;
if (start == NULL)
return NULL;
node = start;
while(node != NULL)
{
if (node->data == data)
return node;
node = node->next;
}
return NULL;
}
int delete(struct node **start, int data)
{
struct node *p, *prev, *next, *to_free;
if (start == NULL) // protection
return 0;
p = find(*start, data); // find p to be removed
if (p == NULL)
return 0;
if (*start == NULL)
return 0; // protection
if(*start == p) // head == p
{
if((*start)->next !=NULL)
{
*start = (*start)->next; // remember next
free(p);
printf("Head removed\n");
return 1;
}
else // the only node
{
free(p);
printf("Last node removed\n");
*start = NULL;
return 1;
}
}
// p != start:
next = *start;
while (next != NULL)
{
prev = next;
to_free = next->next; // candidate to be freed
if( to_free == p )
{
prev->next = to_free->next; // connect nodes before deletion
free(to_free); // now free the remembered `next`
to_free = NULL; // so it does not point to the released memory
return 1;
}
next = next->next; // this node was not a match
} //while
return 0;
}
int main() {
list* new_list = list_create();
node *n1 = node_new(1);
node *n2 = node_new(2);
node *n3 = node_new(3);
// list is empty
print_list(new_list);
prepend_node(new_list, n1);
prepend_node(new_list, n2);
prepend_node(new_list, n3);
// list has 3 elements
print_list(new_list);
delete(&new_list->head, 3);
print_list(new_list);
delete(&new_list->head, 1);
print_list(new_list);
delete(&new_list->head, 2);
// list has 2 elements
print_list(new_list);
printf("head: %p\n",new_list->head);
print_list(new_list);
free (new_list); // after deleting all elements, delete the list itself
return 0;
}
错误消息也指的是哪个免费的?有两个,但您没有给出行号…错误在if语句中显示为free(list);在这种情况下,您需要提供呼叫代码和节点的定义。请完成此问题。我不确定您为什么不能发布完成此问题的代码。
#include <stdio.h>
#include <stdlib.h>
// Basic simple single list implementation to illustrate
// a proper deletion of the node which has a specfic data value.
// Node in List
typedef struct node {
int data;
struct node* next; // pointer to next node
}node;
// List structure
typedef struct list {
node* head; // The entry point into a linked list. If the list is empty then the head is a null reference.
} list;
// Create list
list* list_create()
{
list* new_list = malloc(sizeof(list));
if(new_list == NULL)
return NULL; // protection
new_list->head = NULL; // If the list is empty then the head is a null reference. no elements in the list
return new_list; // return created new list
}
// returns newly created node
node* node_new(int data)
{
node* new_node = malloc(sizeof(node)); // allocate memory for the node
if (new_node == NULL)
return NULL; // protection
new_node->data = data; // remember the data
new_node->next = NULL; // no next node
return new_node; // return new created node
}
// The method creates a node and prepends it at the beginning of the list.
//
// Frequently used names for this method:
//
// insert at head
// add first
// prepend
//
// returns new head or NULL on failer
node* prepend_node(list* in_list, node* new_node)
{
// Add item to the front of the in_list, return pointer to the prepended node (head)
if(in_list == NULL)
return NULL;
if(new_node == NULL) // problem, not enough memory
return NULL; // in_list->head has not changed
/*
new_node
|*| --> NULL
next
*/
if(in_list->head == NULL) // if list is empty
{
in_list->head = new_node; // the new_node becomes a head
}
else // list already have a head node
{
/*
|2|-->|1|-->NULL
^
|
*
head (2) (list pointer)
*/
new_node->next = in_list->head; // now, the new node next pointer points to the node pointed by the list head, see below:
/*
new_node
|3|--> |2|-->|1|-->NULL
^
|
*
head (list pointer)
*/
in_list->head = new_node; // the list head has to move to new_node ( a new prepanded node)
/*
new_node
|3|--> |2|-->|1|-->NULL
^
|
*
head (3) (list pointer)
*/
}
return in_list->head; // we are returning pinter to new_node
}
// Print out list
void print_list(list* in_list)
{
node* node;
if (in_list == NULL)
{
return;
}
if (in_list->head == NULL)
{
printf("List is empty!\n");
return;
}
printf("List: ");
node = in_list->head;
while(node != NULL)
{
printf(" %d", node->data);
node = node->next;
}
printf("\n");
}
struct node *find(struct node *start, int data) // find p to be removed
{
node* node;
if (start == NULL)
return NULL;
node = start;
while(node != NULL)
{
if (node->data == data)
return node;
node = node->next;
}
return NULL;
}
int delete(struct node **start, int data)
{
struct node *p, *prev, *next, *to_free;
if (start == NULL) // protection
return 0;
p = find(*start, data); // find p to be removed
if (p == NULL)
return 0;
if (*start == NULL)
return 0; // protection
if(*start == p) // head == p
{
if((*start)->next !=NULL)
{
*start = (*start)->next; // remember next
free(p);
printf("Head removed\n");
return 1;
}
else // the only node
{
free(p);
printf("Last node removed\n");
*start = NULL;
return 1;
}
}
// p != start:
next = *start;
while (next != NULL)
{
prev = next;
to_free = next->next; // candidate to be freed
if( to_free == p )
{
prev->next = to_free->next; // connect nodes before deletion
free(to_free); // now free the remembered `next`
to_free = NULL; // so it does not point to the released memory
return 1;
}
next = next->next; // this node was not a match
} //while
return 0;
}
int main() {
list* new_list = list_create();
node *n1 = node_new(1);
node *n2 = node_new(2);
node *n3 = node_new(3);
// list is empty
print_list(new_list);
prepend_node(new_list, n1);
prepend_node(new_list, n2);
prepend_node(new_list, n3);
// list has 3 elements
print_list(new_list);
delete(&new_list->head, 3);
print_list(new_list);
delete(&new_list->head, 1);
print_list(new_list);
delete(&new_list->head, 2);
// list has 2 elements
print_list(new_list);
printf("head: %p\n",new_list->head);
print_list(new_list);
free (new_list); // after deleting all elements, delete the list itself
return 0;
}
List is empty!
List: 3 2 1
Head removed
List: 2 1
List: 2
Last node removed
List is empty!
head: (nil)
List is empty!