我目前正在应对 Advent of Code 2022 Day 9 挑战,并在释放我的 C 程序中动态分配的链表时遇到了意外问题。尽管我的代码运行顺利而无需释放链接列表,但通过释放内存来遵循最佳实践会导致意外行为。以前,使用相同链表释放函数的类似代码可以完美运行。我很困惑是什么导致了这种差异。
这是我的代码相关部分的精简版本:(或者您也可以看到完整的代码这里)
// ... some code ....
void freeLinkList(IntPairNode *linkList) {
while (linkList != NULL) {
IntPairNode *temp = linkList;
linkList = linkList->next;
free(temp);
}
}
int findVisited(IntPair *pairList, const Instruction *instructList) {
// pairList and instructList must be properly terminated.
if (pairList[0].isNull == '\0' || pairList[1].isNull == '\0') {
perror("pairList must have at least 2 elements");
return -1;
}
IntPairNode *linkList = malloc(sizeof(IntPairNode));
linkList->x = 0;
linkList->y = 0;
int linkListLength = 1;
// ...
// freeLinkList(linkList); // problemetic line
return linkListLength;
}
// ... some helper function ....
int main(int argc, char *argv[]) {
FILE *file = NULL;
if (!fileOpener(argc, argv, &file)) {
return 1;
}
Instruction *instructList = buildInstructList(file);
if (instructList == NULL) {
printf("Failed to build instruction list.\n");
return 1;
}
fclose(file);
IntPair pairList1[3];
IntPair pairList2[11];
for (int i = 0; i < 2; i++) {
pairList1[i].x = 0;
pairList1[i].y = 0;
pairList1[i].isNull = 'F';
}
pairList1[2].isNull = '\0';
for (int i = 0; i < 10; i++) {
pairList2[i].x = 0;
pairList2[i].y = 0;
pairList2[i].isNull = 'F';
}
pairList2[10].isNull = '\0';
int visited1 = findVisited(pairList1, instructList);
printf("%d\n", visited1); // always works
int visited2 = findVisited(pairList2, instructList);
printf("%d\n", visited2);
free(instructList);
}
当尝试使用
findVisited
函数释放链表时,问题特别出现在 freeLinkedList
函数中。但是,当我注释掉 freeLinkList(linkList)
行时,程序运行没有任何问题,尽管我知道这可能会导致内存泄漏。
对于如何解决此内存管理问题同时确保正确释放链表的任何见解或建议,我将不胜感激。谢谢!
IntPairNode *linkList = malloc(sizeof(IntPairNode)); linkList->x = 0; linkList->y = 0; int linkListLength = 1; // ... // freeLinkList(linkList); // problemetic line
请注意,您尚未为
next
结构体的 linkList
成员赋值。该值是不确定的,与 NULL
不同,因此您的 freeLinkList
函数看不到列表仅包含一个节点,并最终尝试取消引用未初始化的指针,从而导致未定义的行为。