I am building an array and I want it to be a fixed size so that as I read in a file it only stores the last 10 commands. The file seems to read in correctly and it looks right when I print it but for some reason my memory is not getting freed.
MAX is set to 1000
and historySize is read earlier from the user. I ran valgrind on my code and when the calls to these functions are commented out I do not have any leaks.
I have a char ** history under my #includes
Here is my code
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);
}
I do have a function that cleans the history and it looks like this
void cleanHistory()
{
int i;
if(history != NULL)
{
for(i=0;i<historySize;i++)
{
free(history[i]);
history[i] = NULL;
}
free(history);
history = NULL;
}
}
When you allocate memory with
malloc, the chunk of memory allocated is not initialized. That means that if you do something likehistory[pos] != NULLmight actually be true even if you haven’t put anything there.To be certain that the allocated memory is initialized, either use
callocormemset.Edit
To be more specific, this part of your code will behave badly:
If you are not lucky,
history[pos]will contain some old data, which means you will try tofreesomething you have not allocated.As a small side-note, you should be looping while
fgetsdoesn’t returnNULL. As it is now you don’t check for errors fromfgets. Something like this:Then you don’t need the double calls to
fgets, and you will stop looping on both error and end of file.