Is free memory allocated in another function?

I'm trying to learn C, and I'm currently trying to write a basic stack data structure, but I can't get the basic malloc / free to the right.

Here is the code I used (I just post a small part here to illustrate the specific problem, not the general code, but the error message was generated just by running this sample code in valgrind )

 #include <stdio.h> #include <stdlib.h> typedef struct Entry { struct Entry *previous; int value; } Entry; void destroyEntry(Entry entry); int main(int argc, char *argv[]) { Entry* apple; apple = malloc(sizeof(Entry)); destroyEntry(*(apple)); return 0; } void destroyEntry(Entry entry) { Entry *entry_ptr = &entry; free(entry_ptr); return; } 

When I run it through valgrind with --leak-check=full --track-origins=yes , I get the following error:

 ==20674== Invalid free() / delete / delete[] / realloc() ==20674== at 0x4028E58: free (vg_replace_malloc.c:427) ==20674== by 0x80485B2: destroyEntry (testing.c:53) ==20674== by 0x8048477: main (testing.c:26) ==20674== Address 0xbecc0070 is on thread 1 stack 

I think this error means that destroyEntry functions destroyEntry not allowed to modify memory explicitly allocated in the main. It is right? Why can't I allocate free memory that I allocated in main in another function? (and is this behavior somehow specific to the main one?)

+63
c memory-management pointers malloc free
Jun 17 '12 at 12:11
source share
3 answers

Whenever you pass a parameter to a function, a copy is executed, and the function works on that copy. So, in your case, you are trying to copy the original object free , which makes no sense.

You must change your function to take a pointer, and then you can call free directly on that pointer.

+50
Jun 17 '12 at 12:14
source share

This is a pass by value, which means that a copy is being created, so you are trying to free up memory where the local entry variable is located. Please note that entry is an object with automatic storage duration, and the memory in which it resides will be automatically freed when your program leaves the scope of destroyEntry .

 void destroyEntry(Entry entry) { Entry *entry_ptr = &entry; free(entry_ptr); return; } 

Your function should take a pointer (pass by reference):

 void destroyEntry(Entry *entry) { free(entry); } 

Then, instead of destroyEntry(*(apple)); you just call destroyEntry(apple); . Please note: if there is no other function associated with the destroyEntry function, it is redundant and it is better to just call free(apple) .

+35
Jun 17 '12 at 12:16
source share

The other answers here point to the main problem - because you are looking for your apple, when you call destroyEntry in main (), it passes by reference, creating a copy.

Even when you know your problem, it helps to return to the error and try to connect the text of what you see to the problem, so the next time it appears, you are likely to quickly. I find that C and C ++ errors sometimes seem insanely ambiguous.

As a rule, when I have problems with freeing pointers or deleting objects, I like typing addresses, especially when I select them and when I try to free them. valgrind already gave you the address of a bad pointer, but helps to compare it with a good one.

 int main() { Entry * apple; apple = malloc(sizeof(Entry)); printf("apple address = %p", apple); // Prints the address of 'apple' free(apple); // You know this will work } 

After that, you will notice that the printf () operator gave you an address similar to 0x8024712 (just making up the address in the right general range), but your output valgrind gave 0x4028E58. You would notice that they are in two different places (in fact, "0x4 ..." is on the stack, not the heap from which malloc () is allocated, but I assume that you are just starting and not the red flag for you) , so you know that you are trying to free memory due to the wrong place, therefore, "invalid free ()".

So, from there you can say to yourself: "Okay, somehow my pointer is getting corrupted." You have already blamed your problem on a small, compiled example, so you don’t need much time to solve this problem.

TL; DR - when working with errors related to pointers, try printing addresses or finding them in your favorite debugger. This often at least points you in the right direction.

None of this should prevent you from posting your question to Stack Exchange, of course. Hundreds of programmers are likely to benefit from doing this.

+9
Jun 20 '12 at 15:39
source share



All Articles