【问题标题】:Valgrind memory test error in C. Memory leak issueC中的Valgrind内存测试错误。内存泄漏问题
【发布时间】:2021-01-03 02:21:36
【问题描述】:

老实说,我不知道如何解释这一点,但我的代码中存在内存泄漏。代码通过了除此之外的所有测试。该函数是一个从内存中卸载字典的卸载函数。

// Unloads dictionary from memory, returning true if successful else false
bool unload(void)
{
    for ( int i = 0 ; i < N ; i++)
    {
        node *head = table[i];
        node *cursor = head;
        node *tmp = head;
        
        while(cursor != NULL)
        {
            cursor = cursor->next;
            free(tmp);
            tmp = cursor;
        }
    }
    return true;
}

这个函数加载字典:

// Loads dictionary into memory, returning true if successful else false
bool load(const char *dictionary)
{
    char word[LENGTH + 1];
    FILE *file = fopen(dictionary,"r");
    if (file == NULL) return false;
    
    while (fscanf(file,"%s",word) != EOF)
    {
        node *n = malloc(sizeof(node));
        if (n == NULL) return false;
        strcpy(n->word,word);
        n->next = NULL;
        
        int hash_index = hash(word);
        if (table[hash_index] == NULL)
        {
            table[hash_index] = n;
        }
        else 
        {
            n->next = table[hash_index];
            table[hash_index] = n;
        }
        total++;
    }
    return true;
}

任何帮助将不胜感激!

【问题讨论】:

  • 如果可能的话,看看所有的 malloc 调用也会很有帮助。
  • @ViktorLatypov 抱歉,我已经编辑了帖子以显示加载功能。

标签: c data-structures hashtable cs50


【解决方案1】:

原来我忘记关闭文件了!

// Loads dictionary into memory, returning true if successful else false
bool load(const char *dictionary)
{
    char word[LENGTH + 1];
    FILE *file = fopen(dictionary,"r");
    if (file == NULL) return false;
    
    while (fscanf(file,"%s",word) != EOF)
    {
        node *n = malloc(sizeof(node));
        if (n == NULL) return false;
        strcpy(n->word,word);
        n->next = NULL;
        
        int hash_index = hash(word);
        if (table[hash_index] == NULL)
        {
            table[hash_index] = n;
        }
        else 
        {
            n->next = table[hash_index];
            table[hash_index] = n;
        }
        total++;
    }
    fclose(file);
    return true;
}

【讨论】:

  • 当我在具有足够调试信息的程序上使用 valgrind 时,valgrind 会告诉内存泄漏的原因,在这种情况下,它会告诉调用 fopen() 的行会导致泄漏(以及所有函数fopen()load() 函数之前调用分配空间和调用树)。您为编译器使用哪些调试标志?至少使用-g 并禁用或最小化优化器。 valgrind.org/docs/manual/quick-start.html
  • OT:如果您可以编写函数,以便他们获得指向 struct'a 的指针和他们需要初始化的数组并且不使用 static 或全局数据。在这种情况下,table 应该用一个指针赋予这个函数,这样你以后就有可能将它用于不同的字典,并且当你以后想要添加多线程或代码在一个图书馆。
猜你喜欢
  • 2020-03-31
  • 2016-03-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-28
  • 2021-11-28
  • 2023-03-25
  • 2015-06-28
相关资源
最近更新 更多