c - 内存泄漏和可能的 malloc 错误

标签 c

我正在构建一个数组,我希望它的大小固定,这样当我读入一个文件时它只存储最后 10 个命令。该文件似乎读入正确,打印时看起来也正确,但由于某种原因,我的内存没有被释放。 MAX 设置为 1000 historySize 是较早从用户那里读取的。我在我的代码上运行了 valgrind,当对这些函数的调用被注释掉时,我没有任何泄漏。

我的#includes 下有一个 char ** 历史记录

这是我的代码

void setupHistoryFile()
{
    char string[MAX];
    FILE *fp;
    int len;
    int pos = 0;
    fp = fopen(".ush_history","r");
    if(fp == NULL)
    {
        //create the file
        fp = fopen(".ush_history","w");
    }
    else
    {
        history = (char**)malloc(historySize * sizeof(char*));//setup history file
        fgets(string,MAX,fp);
        len = strlen(string);
        if(string[len-1]=='\n')
            string[len-1]='\0';
        while(!feof(fp))
        {
            if(history[pos] != NULL)
            {
                free(history[pos]);
                history[pos]=NULL;
            }
            history[pos] = (char*)malloc((strlen(string)+1) * sizeof(char));
            //printf("Should be copying %s\n",string);          
            strcpy(history[pos], string);           
            pos++;
            pos = pos % historySize;
            fgets(string,MAX,fp);
            len = strlen(string);
            if(string[len-1]=='\n')
                string[len-1]='\0';
        }
    }
    fclose(fp);
}

我确实有一个清除历史记录的功能,它看起来像这样

void cleanHistory()
{
    int i;
    if(history != NULL)
    {
        for(i=0;i<historySize;i++)
        {
            free(history[i]);
            history[i] = NULL;
        }
        free(history);
        history = NULL;
    }
}

最佳答案

当您使用malloc 分配内存时,分配的内存块不会被初始化。这意味着如果您执行类似 history[pos] != NULL 的操作,即使您没有在此处放置任何内容,它实际上也可能为真。

要确保分配的内存已初始化,请使用 callocmemset

编辑 更具体地说,您的这部分代码将表现不佳:

if(history[pos] != NULL)
{
    free(history[pos]);
    history[pos]=NULL;
}

如果你运气不好,history[pos] 将包含一些旧数据,这意味着你将尝试释放一些你没有分配的东西。

作为一个小旁注,您应该在 fgets 不返回 NULL 时循环。现在您不检查来自 fgets 的错误。像这样:

while (fgets(...) != NULL)

那么您就不需要对 fgets 的两次调用,并且您将停止在错误和文件结尾处循环。

关于c - 内存泄漏和可能的 malloc 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9075886/

相关文章:

c - C中链表的合并排序代码仅对一半元素进行排序

函数错误的冲突类型

objective-c - 我可以创建只对我的类可见的 C 函数,它被分成多个文件吗?

c - Eclipse:为所有新 C 项目选择默认调试器

c - 在 C 中将动态数组从一个函数内部传递到另一个函数

c - 在C中逐行逐字符读取文件

c - 考虑到优先级和结合性,如何解决这个表达式?

c - 在不编译的情况下获取 C 程序的输出

c++ - C 中的 Windows 应用程序

c - 如何在指针中保存多种类型的数据