【问题标题】:Freeing a strdup inside of a linked list释放链表内的 strdup
【发布时间】:2021-09-24 17:54:15
【问题描述】:

我有一个链接列表,我试图在其中释放一个 char*,我使用了 strdup

这些是我在列表中添加节点的方法:

  node* add_first(char* name,  node* head) {
          node* new_node;
          new_node = (node*)malloc(sizeof(node));
          char* c = strdup(name);
          new_node->name = c;
          new_node->next = head;
          head = new_node;
          return head;
  }

node * add_last(char* name, node *head ) {
      node* new_node;
      node* current;
      new_node = (node*)malloc(sizeof(node));
      char* c = strdup(name);
      new_node->name = c;
      new_node->next = NULL;

      if ( head == NULL ){
              head = new_node;
      }
      else{
              current = head;
              while ( current->next ) current = current->next;
              current->next = new_node;
      }

          return head;
  }

移除节点:

 int remove_last( node **head, char **ret )
  {
          int result = *head == NULL ? -1 : 0;

          if ( result == 0 )
          {
                  while( ( *head )->next != NULL ) head = &( *head )->next;

                  *ret = strdup( ( *head )->name );
                  free( *head );
                  *head = NULL;
          }

          return result;
  }

为了清理列表:

void deleteList(node** head){
      node* current = *head;
      node* next;

      while(current != NULL){
              next = current->next;
              free(current->name);
              free(current);
              current = next;
      }

      *head = NULL;
  }

但是 valgrind 说我“肯定丢失了”我在 add_last 函数中的 strdup 的记忆(但奇怪的是不是我的 add_first 函数)。

为什么它只发生在 add_last 方法上,我怎样才能正确释放它?我以为我正在释放 deleteList 方法中的所有节点和名称?

【问题讨论】:

    标签: c memory-management linked-list free strdup


    【解决方案1】:

    您不必要地复制了最后一个节点删除算法中的字符串,并泄漏了原始字符串。该算法应该找到列表中的最后一个节点,将name 指针的所有权传递给输出参数,然后删除节点而不删除名称(因为输出参数现在拥有它) .

    即你应该按照这些思路做一些事情(公平警告,未经编译测试,但你希望得到这个想法):

    int remove_last( node **head, char **ret )
    {
        int res = -1;
        if (*head)
        {
            // find last node in the list
            while ((*head)->next)
                head = &(*head)->next;
    
            // out-param takes ownership
            *ret =(*head)->name;
    
            // free last node *without* freeing the string
            free(*head);
            *head = NULL;
    
            // result indicates success
            res = 0;
        }
        return res;
    }
    

    【讨论】:

      猜你喜欢
      • 2014-09-20
      • 2018-05-14
      • 1970-01-01
      • 2014-09-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-08
      • 2020-12-04
      相关资源
      最近更新 更多