【问题标题】:Freeing pointers in structs pointing to other structs释放结构中指向其他结构的指针
【发布时间】:2015-08-16 05:08:14
【问题描述】:

假设我有一些数据结构,其中结构具有指向其他结构的指针,例如链表。列表中的每个元素都有一个指向列表中另一个元素的指针

struct node{
  char* data;
  node* next;
};

当释放分配给这个结构的内存时,我知道我需要首先专门释放数据,因为我必须专门为它分配内存。但是接下来呢?它指向另一个节点,我相信释放它会释放下一个指向的实际节点。

清理时只释放整个节点是否足够,或者有什么方法可以释放指针而不释放它指向的结构?

【问题讨论】:

  • 您要删除一项还是整个列表?无论哪种方式,free() 只释放它传递的指针;它不知道或释放该结构所指向的任何数据。
  • 我不明白为什么你需要为next分配内存?
  • 不要考虑释放指针——考虑释放你分配的内存块。一旦不再需要该块,就用一个空闲来平衡每个分配......可能有一百个指向同一个块的指针,你仍然只需要释放它一次,或者你可以有指向你不需要的东西的指针动态分配你根本不需要释放的。

标签: c pointers struct


【解决方案1】:

这取决于您如何在内存中构建结构。任何malloc 都必须与free 平衡。一旦指向的next 节点被释放,它就不再有效。

// create root
node* n1 = calloc(1, sizeof(node));

// create/link another node
n1->next = calloc(1, sizeof(node));

// destroy/unlink 2nd node
free(n1->next);
n1->next = NULL;

// destroy 1st node
free(n1);

【讨论】:

    【解决方案2】:

    没有像释放指针这样的东西,你只能释放指针指向的内存——所以如果你想删除链表的单个元素,您必须更新前一项的next 指针,使其指向要删除的元素的next(可能是NULL),然后再删除它。

    void deleteNode(struct node **list, struct node *element)
    {
        /* first node? */
        if (element == *list)
        {
            *list = element->next;
            free(element->data);
            free(element);
            /* now list points to the second element, if any */
        }
        else
        {
            /* find previous node */
            struct node *p = *list;
            while (p->next != element) p = p->next;
    
            /* adjust next pointer */
            p->next = element->next;
            free(element->data);
            free(element);
        }
    }
    

    请注意,使用单链表不适合随机删除的大列表,因为您每次都必须从头开始搜索列表。

    对于删除一个整个链表,有一种迭代和递归的方法,但我没有在这里显示代码,因为据我了解你的问题,这不是你想做的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多