Weird change in program when using free()
I'm a bit confused.
I'm writing a very simple file system that basically:
-reads in a block of data from a file -gets a hash from that block -search a linked-list for that hash -if not found, append -if found, do nothingThe problem:
When I don't use free, the program is a lot slower (probably leaking?).When I use free, the program runs faster, finishes with block sizes of 128 and 256, but crashes when I try 512 (crashes in insert). I'm working in visual studios, and it just crashes. I get the "VS stopped working.." message which provides no insight.
On top of that, I get much different results when I use free vs. when I don't use it.
Any help would be very much appreciated.
开发者_如何学运维Okay, some code (abbreviated):
struct list_el
{
char* hash;
struct list_el* next;
struct list_el* prev;
};
typedef struct list_el item;
item* head, *tail;
void ins(item* ins)
{
item* iterator = (item*)malloc(sizeof(item));
if(iterator == NULL)
{
printf("out of memory\n");
exit(1);
}
else if(head != NULL)
{
iterator = head;
while(iterator != NULL)
{
if(strcmp(iterator->hash, ins->hash) == 0)
{
//free(iterator); (problem line)
matches++;
return;
}
else if(iterator->next != NULL)
iterator = iterator->next;
else
break;
}
}
unique_blocks++;
if(head == NULL)
{
head = ins;
ins->prev = NULL;
}
else
{
tail->next = ins;
ins->prev = tail;
}
tail = ins;
ins->next = NULL;
}
int main()
{
unsigned char* c = (unsigned char*)malloc(BLOCKSIZE+1);
if(c == NULL)
exit(1);
FILE* fp = fopen("input2","r");
if(fp == NULL)
exit(1);
int i = 0;
char* answer = (char*)malloc(sizeof(char)*90);
if(answer == NULL)
exit(1);
item* ins_item;
char ch;
do
{
if(i == BLOCKSIZE)
{
i = 0;
answer = sha1((unsigned char*)c);
ins_item = (item*)malloc(sizeof(item));
if(ins_item == NULL)
exit(1);
ins_item->hash = answer;
ins(ins_item);
}
else
{
ch = fgetc(fp);
bytes_read++;
c[i] = ch;
i++;
}
}while(ch != EOF);
fclose(fp);
return 0;
}
In your ins()
function you:
malloc()
memory and useiterator
to point to itA few statements later you do
iterator = head
, which means that you lost the pointer to the allocated memory area and have a major memory leakThen a few statement after that you do/do not (depending on the comment)
free()
the item pointed to by the iterator while it is still in your list, while you probably wanted to free the area frommalloc()
EDIT:
Why do you allocate memory for the iterator? Usually list iterators are simple pointers that just point to whatever item the code is currently examining.
EDIT 2:
The crash is most probably caused by your program accessing freed (and thus anavailable) memory that is still part of your list.
Freed memory is not necessarily returned to the system. Depending on how the heap allocator works it could even be allocated again to your program via another malloc()
call. When your program tries to access it again it could have very different data than expected.
Two other points:
Keep your identifiers unique within the same scope. It may not make the compiler stop, but it sure makes the human brain stop. E.g. you should not have an
ins()
function with anins
parameter.Visual Studio has a debugger that (I'm told) is quite good. Learning how to use it would help you a lot.
Also why do you do:
while(iterator != NULL)
{
if(strcmp(iterator->hash, ins->hash) == 0)
{
//free(iterator); (problem line)
matches++;
return;
}
else if(iterator->next != NULL)
iterator = iterator->next;
else
break;
}
This is functionally equivalent to:
while(iterator != NULL)
{
if(strcmp(iterator->hash, ins->hash) == 0)
{
//free(iterator); (problem line)
matches++;
return;
}
iterator = iterator->next;
}
But your version is longer and more likely to develop errors later.
精彩评论