|
发表于 2023-6-26 14:13:23
|
显示全部楼层
本帖最后由 歌者文明清理员 于 2023-6-26 14:24 编辑
在代码中,我们传递给he()函数的是head指针所指向的链表的地址。he()函数中对链表进行了修改,将新的链表赋值给了L,并返回了新的头结点。所以,在ji()函数中,可以释放掉head指针所指向的内存空间,因为它不再被使用。
然而,问题出现在你尝试在释放掉head之后继续使用它来打印结果。即使你之后重新设置了新的链表,但在释放head后,该指针变成了悬空指针(dangling pointer),指向了已经释放掉的内存。当你使用悬空指针时,会导致未定义的行为,其中包括错误的答案结果。
为了解决这个问题,你可以调整代码如下:
- L = he(head, L);
- freeList(L); // 释放掉旧的链表
复制代码
通过释放新的链表L,而不是释放已经被释放的head,可以避免悬空指针问题,并确保答案结果正确。
更详细的解释:
当我们调用freeList(head)释放掉head指针所指向的链表内存后,该内存空间将被标记为可重用。然而,在之后的代码中,你通过重新分配内存给head指针来创建一个新的链表。
这里产生了一个问题,即悬空指针(dangling pointer)。悬空指针是指指向已被释放的内存空间的指针。在这种情况下,head指针因为之前的释放操作而成为了悬空指针,它指向了一块不可预知的内存区域。
当你尝试在L = he(head, L);之后使用head指针来打印结果时,你实际上在访问一个无效的内存区域。这可能会导致程序崩溃、产生意外的输出或其他未定义的行为,包括错误的答案结果。
完整代码:
- #include <stdio.h>
- #include <stdlib.h>
- typedef struct Node *node;
- struct Node
- {
- int x;
- int z;
- node next;
- };
- node read();
- void print(node list);
- node he(node list1, node list2);
- node ji(node list1, node list2);
- void freeList(node head);
- node read()
- {
- int i;
- scanf("%d", &i);
- node head = (node)malloc(sizeof(struct Node));
- head->next = NULL;
- node p = head;
- while (i--)
- {
- node temp = (node)malloc(sizeof(struct Node));
- scanf("%d %d", &temp->x, &temp->z);
- p->next = temp;
- p = p->next;
- }
- p->next = NULL;
- return head;
- }
- node he(node list1, node list2)
- {
- node temp;
- node head = (node)malloc(sizeof(struct Node));
- head->next = NULL;
- node p = head;
- if (list2->next == NULL)
- return list1;
- else
- {
- list1 = list1->next;
- list2 = list2->next;
- while (list1 && list2)
- {
- temp = (node)malloc(sizeof(struct Node));
- if (list1->z == list2->z)
- {
- temp->x = list1->x + list2->x;
- temp->z = list1->z;
- list1 = list1->next;
- list2 = list2->next;
- }
- else if (list1->z > list2->z)
- {
- temp->x = list1->x;
- temp->z = list1->z;
- list1 = list1->next;
- }
- else
- {
- temp->x = list2->x;
- temp->z = list2->z;
- list2 = list2->next;
- }
- p->next = temp;
- p = p->next;
- }
- for (; list1; list1 = list1->next)
- temp = (node)malloc(sizeof(struct Node)), temp->x = list1->x, temp->z = list1->z, p->next = temp, p = p->next;
- for (; list2; list2 = list2->next)
- temp = (node)malloc(sizeof(struct Node)), temp->x = list2->x, temp->z = list2->z, p->next = temp, p = p->next;
- p->next = NULL;
- return head;
- }
- }
- node ji(node list1, node list2)
- {
- node t, L = (node)malloc(sizeof(struct Node));
- L->next = NULL;
- list1 = list1->next;
- list2 = list2->next;
- for (list1; list1; list1 = list1->next)
- {
- node temp;
- node head = (node)malloc(sizeof(struct Node));
- head->next = NULL;
- node p = head;
- for (t = list2; t; t = t->next)
- {
- temp = (node)malloc(sizeof(struct Node));
- temp->x = list1->x * t->x;
- temp->z = list1->z + t->z;
- p->next = temp;
- p = p->next;
- }
- p->next = NULL;
- L = he(head, L);
- freeList(head); // 释放掉旧的链表
- }
- //L->next = NULL;
- return L;
- }
- void print(node list)
- {
- if (list->next)
- {
- list = list->next;
- while (list)
- {
- printf("%d %d", list->x, list->z);
- list = list->next;
- if (list)
- printf(" ");
- }
- }
- else
- printf("0 0");
- }
- void freeList(node head)
- {
- node temp;
- while (head != NULL)
- {
- temp = head;
- head = head->next;
- free(temp);
- }
- }
- int main()
- {
- node list1, list2;
- list1 = read();
- list2 = read();
- node jiResult = ji(list1, list2);
- node heResult = he(list1, list2);
- print(jiResult);
- printf("\n");
- print(heResult);
- freeList(jiResult);
- freeList(heResult);
- freeList(list1);
- freeList(list2);
- return 0;
- }
复制代码
经过修改后的代码中,在ji()函数中,我们通过将新的链表赋值给L,并在之后释放掉旧的链表head来避免悬空指针问题。然后,我们可以使用L来打印答案结果。同时,在main()函数中,我们也释放了所有动态分配的内存,包括jiResult、heResult、list1和list2。这样可以确保所有的内存被正确地释放,避免内存泄漏。 |
|