我正在构建一个数组,我希望它是一个固定的大小,以便我在一个文件中读取它只存储最后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);
}
Run Code Online (Sandbox Code Playgroud)
我确实有一个清理历史的功能,它看起来像这样
void cleanHistory()
{
int i;
if(history != NULL)
{
for(i=0;i<historySize;i++)
{
free(history[i]);
history[i] = NULL;
}
free(history);
history = NULL;
}
}
Run Code Online (Sandbox Code Playgroud)
分配内存时malloc,分配的内存块未初始化.这意味着如果你做了类似的事情,history[pos] != NULL即使你没有在那里放任何东西也可能是真的.
要确定已分配的内存已初始化,请使用calloc或memset.
编辑 更具体地说,这部分代码表现不佳:
if(history[pos] != NULL)
{
free(history[pos]);
history[pos]=NULL;
}
Run Code Online (Sandbox Code Playgroud)
如果你不幸运,history[pos]将包含一些旧数据,这意味着你将尝试free一些你没有分配的东西.
作为一个小注意事项,你应该循环fgets而不返回NULL.因为现在你不检查错误fgets.像这样的东西:
while (fgets(...) != NULL)
Run Code Online (Sandbox Code Playgroud)
然后你不需要双重调用fgets,你将停止循环错误和文件结束.