Reputation: 57
I'm writing a program in C for my class, and I'm doing pair programming. I'm wondering how it isn't crashing the program. My partner added this block of code below, and I ran valgrind to test and see if there were any memory leaks, it seemed fine - then again, im new at this. Anyways, I was wondering how this code can work because when I free curr, the next thing that runs is curr = curr->link - but we just freed curr! So how can curr have a link if it is taken out of memory? I thought that something like this wouldn't work.
Here is what my partner wrote:
for(node curr = list->head; curr != NULL; curr = curr->link ){
if (!dflag) printf("%s\n",curr->words);
else printf("[%p]\n",curr);
free(curr->words);
free(curr);
}
Here is what I was thinking of doing in case ^ this ^ crashed:
for (node curr = list->head; curr != NULL; ) {
if (!dflag) printf("%s\n",curr->words);
else printf("[%p]\n",curr);
node prev = curr;
curr = curr->link;
free(prev);
}
Also, here is how we made a node:
typedef struct node *node;
struct node {
cstring words;
node link;
};
Upvotes: 1
Views: 607
Reputation: 54551
Just because you've freed the memory doesn't mean that its contents have been lost. It's likely that your content will remain there for some time until the memory is returned to another caller of malloc()
and the caller writes to it.
Obviously you can't and shouldn’t depend on this. valgrind
should have printed errors relating to accessing freed memory.
This is an instance our old friend, "undefined behavior". Although we can explain why it might behave a certain way, there is no guarantee that this will happen and it is an error by definition to depend on it. For this reason, you're actually more lucky when such things crash, as it's quite possible such things go unnoticed and cause all sorts of strange problems when you least expect it.
Upvotes: 2
Reputation: 97938
You need to compile with -g
flag to get useful valgrind output. The first code is wrong because you cannot make any assumptions on the freed data. And the normal way to define self pointers is like this:
struct node {
cstring words;
struct node *link;
};
Upvotes: 0