仍然能够访问已释放的结构 [英] Still able to access a struct that has been freed

查看:94
本文介绍了仍然能够访问已释放的结构的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以,我有一个结构:

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆