仍然能够访问已释放的结构 [英] Still able to access a struct that has been freed
问题描述
所以,我有一个结构:
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)。
deleteOne will hand the final node in the list to deleteNode so that the memory can be freed. When a node is initialized, no memory is allocated for next, until it is needed. instead, it is initially set to be NULL. This is why I don't free(p->next).
因此,如果我有一个节点列表(假设它们的值为3.5、2.5、1.2 ,3.6)
打印功能将打印以下内容:
So, if I have a list of nodes (let's say their values are 3.5, 2.5, 1.2, 3.6) the print function will print the following:
3.5
2.5
1.2
3.6
然后,如果删除了最后一个节点,则再次打印以下内容打印:
Then, if the final node is deleted, and I print again, the following is printed:
3.5
2.5
1.2
3.6
如果删除另一个节点,则会出现错误,因为我试图释放已经释放的内存。
If I delete another node, I get an error because I'm trying to free memory that has already been freed.
似乎打印仍在访问存储位置,该位置已被释放。但是,如果下一个节点等于NULL,则似乎不应该尝试读取此内容。
我意识到这是不确定的行为,但是我该如何解决?
It seems as though print is accessing a memory location still, that has already been freed. However, it seems like it shouldn't be trying to read this if the 'next' node is equal to NULL. I realize this is undefined behaviour, but how can I fix this?
推荐答案
当 tail节点
被删除,程序员有责任将前一个节点的 next
元素设置为NULL。
When the tail node
of a linked list is deleted, it is the programmer's responsibility to set the previous' node's next
element to NULL.
当 tail节点
被 free()
ed时,内存占用的节点将继续保存为其分配的值(当它是节点时),直到该内存用于其他用途。因此,释放内存后继续引用该内存不是一个好主意。
When the tail node
is free()
ed, the memory that the node occupied will continue to hold the values it was assigned (when it was a node) until that memory is used for another purpose. Hence, it is not a good idea to continue to reference that memory after freeing it.
有时,我编写自己的 free()
函数,以确保传递给free的指针不再能够访问内存。像这样的东西:
Sometimes, I write my own free()
function to ensure that the pointer passed to free is no longer capable of accessing the memory. Something like this:
void myFree(void **ptr)
{
free(*ptr);
*ptr=NULL;
}
然后,当释放尾节点时,父节点的下一个指针将自动释放设置为NULL:
Then, when the tail node is freed, the parent node's next pointer is automatically set to NULL:
void myFreeTailNode(NodeT **head)
{
NodeT *parentNode = NULL;
if(NULL == head)
return;
if(NULL == *head)
return;
if(NULL == (*head)->next)
myFree((void **)head);
else
{
for(parentNode = *head; parentNode->next->next; parentNode=parentNode->next)
/*Do Nothing */ ;
MyFree((void **)&parentNode->next);
}
}
这篇关于仍然能够访问已释放的结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!