创建一个重复链表 returns SIGSEGV
Creating a duplicate linked list returns SIGSEGV
所以我试图创建一个链表的副本,其中包含指向数据的空指针
定义是:
typedef struct SinglyLinkedListNode {
void *data;
struct SinglyLinkedListNode *next;
}SinglyLinkedListNode;
typedef struct SinglyLinkedList {
int size;
struct SinglyLinkedListNode *front;
}SinglyLinkedList;
我克隆链表的函数受到了的启发,唯一的区别是,我的列表没有尾部实现。
这是我的实现
SinglyLinkedListNode *cloneList(SinglyLinkedList *list, SinglyLinkedListNode *head) {
if(head == NULL)
return NULL;
SinglyLinkedListNode *result = (SinglyLinkedListNode *)malloc(sizeof(SinglyLinkedListNode));
result->data = head->data;
if(head->next)
result->next = cloneList(list, head->next);
return result;
}
SinglyLinkedList *cloneFullList(SinglyLinkedList *list) {
if(list == NULL)
return NULL;
SinglyLinkedList *result = (SinglyLinkedList *)malloc(sizeof(SinglyLinkedList));
result->size = list->size;
if(list->front != NULL)
list->front = cloneList(result, list->front);
return result;
}
但是当尝试像这样访问数据时
SinglyLinkedList *list1 = (SinglyLinkedList *)malloc(sizeof(SinglyLinkedList));
list1 = cloneFullList(list); //where list is an already existing list which works correctly
SinglyLinkedListNode *curr1 = (SinglyLinkedListNode *)malloc(sizeof(SinglyLinkedListNode));
curr1 = list1->front;
正在尝试访问 curr1->data
returns 出现分段错误。但是当我尝试通过 curr1 = list->front
访问数据时,数据被正确访问。我克隆链表的函数哪里出错了?
我认为你没有正确理解事情是如何运作的……
malloc 为您的对象分配内存,但不对其进行初始化。
list1 = cloneFullList(列表);
这会将指针分配给一个新的目的地,但会丢失分配的轨道 space,而不会对其进行初始化。
此外,您的 cloneList 不会在最后一个元素上设置 next 指针(当 next 为 null 时),因此它仍未初始化。
对于 cloneFullList 也是如此(你应该只删除 if(list->front != NULL),因为 cloneList 已经处理了 NULL 的情况)。
这部分变量名有误:
if(list->front != NULL)
list->front = cloneList(result, list->front);
// in previous line you modify list not result.
// so result->front contents is undefined
// you also missed the else when list->front is null
return result;
在这两个函数中,您可以使用 calloc 将 NULL 指针或 0 整数作为初始值
几个问题:
在您的主代码中,您为 *list1
分配了内存,但随后立即为 list1
分配了一个不同的值,泄漏了分配的内存。
您的代码犯了与 curr1
类似的错误
函数仅在条件为真时才对next
(或分别为front
)进行赋值,但这些属性应该总是 得到一个值。
有一个分配给 list->front
,应该分配给 result->front
。
没问题,但是 cloneList
的第一个版本确实不需要第一个参数(列表)。你可以只用节点参数来做。
这里是更新的代码:
// No need for the list as first argument:
SinglyLinkedListNode *cloneList(SinglyLinkedListNode *head) {
if(head == NULL)
return NULL;
SinglyLinkedListNode *result = (SinglyLinkedListNode *)malloc(sizeof(SinglyLinkedListNode));
result->data = head->data;
result->next = cloneList(head->next); // No condition here
return result;
}
SinglyLinkedList *cloneFullList(SinglyLinkedList *list) {
if(list == NULL)
return NULL;
SinglyLinkedList *result = (SinglyLinkedList *)malloc(sizeof(SinglyLinkedList));
result->size = list->size;
result->front = cloneList(list->front); // No condition here
return result;
}
int main(void) {
// ... code that creates `list` comes here ...
//
// No calls to malloc here...
SinglyLinkedList *list1 = cloneFullList(list);
SinglyLinkedListNode *curr1 = list1->front;
// ...
return 0;
}
所以我试图创建一个链表的副本,其中包含指向数据的空指针 定义是:
typedef struct SinglyLinkedListNode {
void *data;
struct SinglyLinkedListNode *next;
}SinglyLinkedListNode;
typedef struct SinglyLinkedList {
int size;
struct SinglyLinkedListNode *front;
}SinglyLinkedList;
我克隆链表的函数受到了
这是我的实现
SinglyLinkedListNode *cloneList(SinglyLinkedList *list, SinglyLinkedListNode *head) {
if(head == NULL)
return NULL;
SinglyLinkedListNode *result = (SinglyLinkedListNode *)malloc(sizeof(SinglyLinkedListNode));
result->data = head->data;
if(head->next)
result->next = cloneList(list, head->next);
return result;
}
SinglyLinkedList *cloneFullList(SinglyLinkedList *list) {
if(list == NULL)
return NULL;
SinglyLinkedList *result = (SinglyLinkedList *)malloc(sizeof(SinglyLinkedList));
result->size = list->size;
if(list->front != NULL)
list->front = cloneList(result, list->front);
return result;
}
但是当尝试像这样访问数据时
SinglyLinkedList *list1 = (SinglyLinkedList *)malloc(sizeof(SinglyLinkedList));
list1 = cloneFullList(list); //where list is an already existing list which works correctly
SinglyLinkedListNode *curr1 = (SinglyLinkedListNode *)malloc(sizeof(SinglyLinkedListNode));
curr1 = list1->front;
正在尝试访问 curr1->data
returns 出现分段错误。但是当我尝试通过 curr1 = list->front
访问数据时,数据被正确访问。我克隆链表的函数哪里出错了?
我认为你没有正确理解事情是如何运作的…… malloc 为您的对象分配内存,但不对其进行初始化。 list1 = cloneFullList(列表); 这会将指针分配给一个新的目的地,但会丢失分配的轨道 space,而不会对其进行初始化。
此外,您的 cloneList 不会在最后一个元素上设置 next 指针(当 next 为 null 时),因此它仍未初始化。 对于 cloneFullList 也是如此(你应该只删除 if(list->front != NULL),因为 cloneList 已经处理了 NULL 的情况)。
这部分变量名有误:
if(list->front != NULL)
list->front = cloneList(result, list->front);
// in previous line you modify list not result.
// so result->front contents is undefined
// you also missed the else when list->front is null
return result;
在这两个函数中,您可以使用 calloc 将 NULL 指针或 0 整数作为初始值
几个问题:
在您的主代码中,您为
*list1
分配了内存,但随后立即为list1
分配了一个不同的值,泄漏了分配的内存。您的代码犯了与
类似的错误curr1
函数仅在条件为真时才对
next
(或分别为front
)进行赋值,但这些属性应该总是 得到一个值。有一个分配给
list->front
,应该分配给result->front
。
没问题,但是 cloneList
的第一个版本确实不需要第一个参数(列表)。你可以只用节点参数来做。
这里是更新的代码:
// No need for the list as first argument:
SinglyLinkedListNode *cloneList(SinglyLinkedListNode *head) {
if(head == NULL)
return NULL;
SinglyLinkedListNode *result = (SinglyLinkedListNode *)malloc(sizeof(SinglyLinkedListNode));
result->data = head->data;
result->next = cloneList(head->next); // No condition here
return result;
}
SinglyLinkedList *cloneFullList(SinglyLinkedList *list) {
if(list == NULL)
return NULL;
SinglyLinkedList *result = (SinglyLinkedList *)malloc(sizeof(SinglyLinkedList));
result->size = list->size;
result->front = cloneList(list->front); // No condition here
return result;
}
int main(void) {
// ... code that creates `list` comes here ...
//
// No calls to malloc here...
SinglyLinkedList *list1 = cloneFullList(list);
SinglyLinkedListNode *curr1 = list1->front;
// ...
return 0;
}