C - 排序到列表和内存泄漏

Posted

技术标签:

【中文标题】C - 排序到列表和内存泄漏【英文标题】:C - sorting to list and memory leak 【发布时间】:2020-09-22 11:24:51 【问题描述】:

您好,我正在删除代码中的内存泄漏,但我卡住了。

这里有函数:


char* MakeLowerCase(char* word)

  char* lower = (char *)malloc(sizeof(char)*strlen(word)+1);
  strcpy(lower, word);
  int i = 0;

  for(i = 0; i < strlen(lower); i++)
    lower[i] = tolower(lower[i]);
  
  return lower;


void sortedInsert(Word** pH, Word* new_node)

    Word* current;
    /* Special case for the head end */
    if (*pH == NULL || strcmp(MakeLowerCase((*pH)->word), MakeLowerCase(new_node->word)) == 1)
    
        new_node->pNext = *pH;
        *pH = new_node;
    
    else
    
        /* Locate the node before the point of insertion */
        current = *pH;
        while (current->pNext!=NULL &&
               strcmp(MakeLowerCase(current->pNext->word), MakeLowerCase(new_node->word)) == -1)
        
            current = current->pNext;
        
        new_node->pNext = current->pNext;
        current->pNext = new_node;
    


使用这些功能后,我的整个列表都已排序。但是为了避免 MakeLowerCase 的内存泄漏,我尝试了这样的事情:


void sortedInsert(Word** pH, Word* new_node)

    Word* current;
    /* Special case for the head end */
    if(*pH = NULL)
    
      *pH = new_node;
      return ;
    

    char* word1 = MakeLowerCase((*pH)->word);
    char* word2 = MakeLowerCase(new_node->word);
    if (*pH == NULL || strcmp(word1, word2) == 1)
    
        new_node->pNext = *pH;
        *pH = new_node;
    
    else
    
        /* Locate the node before the point of insertion */
        current = *pH;
        char* word3 = MakeLowerCase(current->pNext->word);
        char* word4 = MakeLowerCase(new_node->word);
        while (current->pNext!=NULL && strcmp(word3, word4) == -1)
        
            current = current->pNext;
        
        new_node->pNext = current->pNext;
        current->pNext = new_node;
    
    free(word1);
    free(word2);


更改后,我的列表没有像之前那样排序(只是其中一部分以奇怪的方式排序)。我做错了什么?

【问题讨论】:

Ofc after current->pNext 我对 word3 和 word4 使用 free() 只需使用 stricmp() 进行比较。 我不能只使用 strcmp() 因为我需要比较小写字母。 我怕你把小写字母 i 看多了:str - i - cmp i=ignorecase 嗯,是的。你说得对。我会检查那个解决方案 【参考方案1】:

您已经注意到,原始方法会泄漏内存。从MakeLowerCase() 返回的内存从未被释放。在您的第二次尝试中,您尝试修复此问题,但现在泄漏了 word3 和 word4。你后来修好了。

主要错误是在您修改后的函数中,您有一个循环推进current,同时将word3 与新项目进行比较。在推进current 之后,您错过了更新word3 inside 循环。而且你也必须释放它。

正如我在评论中提到的,你应该简单地使用 stricmp(),strcmp 的忽略大小写兄弟,所以你不需要所有泄漏的MakeLowerCase()

这是我的短代码。对于链表,我喜欢使用像 Word** 这样的双重间接寻址,因为它减少了边缘情况的数量,从而减少了条件指令的数量。

void sortedInsert(Word** pHead, Word* new_node)

   //*pHead is a possible insertion point for new_node, like *pHead=new_node
   while (*pHead)
   
      if (stricmp(new_node->word, (*pHead)->word) < 0)
         break; //Insertion point found.
      pHead = &(*pHead)->pNext;
   
   //*pHead is the insertion point for new_node, the remaining list at *pHead goes behind us
   new_node->pNext = *pHead;
   *pHead = new_node;

【讨论】:

以上是关于C - 排序到列表和内存泄漏的主要内容,如果未能解决你的问题,请参考以下文章

Python C 包装器内存泄漏

linux内存泄漏怎么查

彻底搞清楚内存泄漏的原因,如何避免内存泄漏,如何定位内存泄漏

避免实体框架查询返回的列表中的内存泄漏

Valgrind 检测到内存泄漏,找不到它 C

在Linux中运行的C程序出现内存泄漏现象,怎么解决?