泄漏内存和可能的malloc错误

时间:2012-01-31 07:25:11

标签: 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;
    }
}

2 个答案:

答案 0 :(得分:7)

使用malloc分配内存时,未分配的内存块未初始化。这意味着如果你做history[pos] != NULL这样的事情,即使你没有在那里做任何事情也可能是真的。

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

修改 更具体地说,这部分代码表现不好:

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

如果您不幸运,history[pos]将包含一些旧数据,这意味着您将尝试free尚未分配的内容。

作为一个小注意事项,您应该在fgets不返回NULL时进行循环播放。现在,您不会检查来自fgets的错误。像这样:

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

然后您不需要对fgets进行双重调用,并且您将停止循环错误和文件结束。

答案 1 :(得分:0)

您为历史记录分配内存,但不进行初始化。这意味着,在历史记录中,可能会发生历史[pos]未分配,也不会为NULL,并且您将尝试释放未分配的内存。