【问题标题】:Got memory leak; how to free this malloc?有内存泄漏;如何释放这个malloc?
【发布时间】:2020-04-17 11:39:22
【问题描述】:
bool check(const char *word)
{
    int length = strlen(word);

    //malloc size of char times length of word plus \0
    char *lower_case = malloc(sizeof(char) * (length + 1));
    lower_case[length + 1] = '\0';

    //change characters to lowercase
    for (int i = 0; i < length; i++)
    {
        lower_case[i] = tolower(word[i]);
    }

    //generate int hash
    int index = generate_hash(lower_case);

    node_ptr trav = hashtable[index];

    while (trav != NULL)
    {
        if (strcmp(trav->word, lower_case) == 0)
        {
            return true;
        }
        trav = trav -> next;
    }
    free(lower_case);

    return false;
}

我从 Valgrind 测试中泄漏了 27 字节的内存;如何释放它?

【问题讨论】:

  • 如果您发布 minimal reproducible example 可能会有所帮助,因为您的代码中可能存在其他泄漏/问题。但是对于泄漏,您可以在return true; 之前执行free(lower_case);
  • 如果您有来自 Valgrind 的问题报告,请在问题中包含问题报告。您没有提到 Valgrind 抱怨内存访问越界,但它确实抱怨。正如其他人已经指出的那样,您还需要创建一个 MCVE (Minimal, Complete, Verifiable Example)(或 MRE 或 SO 现在使用的任何名称)或 SSCCE (Short, Self-Contained, Correct Example)。
  • 样式指南:点 . 和箭头 -&gt; 运算符绑定非常紧密,因为它们是 postfix operators。它们的周围不应有空格。写 trav -&gt; next 不是惯用的 C 语言,表示编码器是 tyro(新手)。使用trav-&gt;next

标签: c malloc valgrind cs50


【解决方案1】:
  • lower_case[length + 1] = '\0'; 写越界,改成[length]
  • 您缺少#include &lt;stdlib.h&gt; 和其他必要的信息。
  • 每次执行return true; 时都会造成内存泄漏。
  • 永远不要将指针隐藏在 typedef 后面,就像 CS-50 这样的垃圾课程所教导的那样。

您应该能够按照以下内容修复代码:

#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdbool.h>

bool check (const char *word) 
{ 
  size_t length = strlen(word);

  char* lower_case = malloc(length + 1);
  if(lower_case == NULL)
  {
    return false;
  }

  //change characters to lowercase
  for (size_t i = 0; i < length; i++)
  {
    lower_case[i] = tolower(word[i]);
  }
  lower_case[length] = '\0'; 

  //generate int hash
  int index = generate_hash(lower_case); 
  bool result = false;
  for(const node* trav = hashtable[index]; trav!=NULL; trav=trav->next)
  {
    if (strcmp(trav->word, lower_case) == 0)
    {
        result = true;
        break;
    }
  }

  free(lower_case);
  return result;
}

node_ptr 类型需要改成node 不带隐藏指针。

【讨论】:

    【解决方案2】:

    malloc 之后立即出现越界访问。

    在这里,您正在越界访问:

    lower_case[length + 1] = '\0';
    

    应该是:

    lower_case[length] = '\0';
    

    检查malloc是否也失败也是一个明智的想法!

    如 cmets 中所述,从循环内部返回时也可能发生内存泄漏。你需要在那里释放:

      if (strcmp(trav->word, lower_case) == 0)
        {
            free(lower_case);
            return true;
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-06-08
      • 2011-01-27
      • 2011-12-10
      • 1970-01-01
      • 2014-08-26
      • 1970-01-01
      • 2020-05-26
      • 1970-01-01
      相关资源
      最近更新 更多