我正在构建一个数组,我希望它的大小固定,这样当我读入一个文件时它只存储最后 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
的操作,即使您没有在此处放置任何内容,它实际上也可能为真。
要确保分配的内存已初始化,请使用 calloc
或 memset
。
编辑 更具体地说,您的这部分代码将表现不佳:
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/