【发布时间】:2014-05-28 19:14:47
【问题描述】:
所以,我有一个结构:
tyepdef struct node {
struct node *next;
double value;
} NodeT, *NodeTP;
我有三个功能:
int deleteNode(NodeTP p)
{
free(p);
p = NULL;
return 1;
}
int deleteOne(NodeTP list)
{
if (list->next != NULL)
deleteOne(list->next);
else
deleteNode(list);
return 1;
}
int print(NodeT list)
{
printf("%lf\n", list.value);
if (list.next != NULL)
print(*list.next);
return 1;
}
deleteOne 会将列表中的最后一个节点交给 deleteNode,以便释放内存。初始化节点时,不会为下一个节点分配内存,直到需要它为止。相反,它最初设置为 NULL。这就是我不释放的原因(p->next)。
所以,如果我有一个节点列表(假设它们的值为 3.5、2.5、1.2、3.6) 打印功能将打印以下内容:
3.5
2.5
1.2
3.6
那么,如果最后一个节点被删除了,我再打印一次,会打印如下:
3.5
2.5
1.2
3.6
如果我删除另一个节点,我会收到错误消息,因为我正在尝试释放已释放的内存。
似乎 print 仍在访问一个已被释放的内存位置。但是,如果“下一个”节点等于 NULL,它似乎不应该尝试读取它。 我意识到这是未定义的行为,但我该如何解决这个问题?
【问题讨论】:
-
我看不到你的调用代码,但 deleteNode() 是否应该接受指向 p 的指针?
-
未定义的行为是未定义的行为。这不是“保证崩溃”或“保证垃圾值”。解决方案:如果你需要访问一些内存,那就不要释放它。
-
p = NULL;在您的deleteNode函数中无效。您所做的只是修改指针的 local 副本。因此,当您调用deleteNode(list);(在此处添加缺少的分号)时,您实际上并没有更改list的值。对deleteNode的调用将freelist指向的内容,但list通过值传递给deleteNode,因此保持不变。