I'm trying to learn C and I'm currently trying to write a basic stack data structure, but I can't seem to get basic malloc
/free
right.
Here's the code I've been using (I'm just posting a small part here to illustrate a specific problem, not the total code, but the error message was generated just by running this example 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's stack
I think this error means that the destroyEntry
function is not allowed to modify memory allocated explicitly in main. Is that right? Why can't I just free
the memory I allocated in main
in another function? (and is this behavior somehow specific to main?)
LihO :
This is passing by value, which means that copy is created, thus you try to free the memory, where local variable entry resides. Note that entry is an object with automatic storage duration and memory where it resides will be freed automatically when your program goes out of scope of destroyEntry function.\n\nvoid destroyEntry(Entry entry)\n{\n Entry *entry_ptr = &entry;\n free(entry_ptr);\n return;\n}\n\n\nYour function should take a pointer (passing by reference):\n\nvoid destroyEntry(Entry *entry)\n{\n free(entry);\n}\n\n\nThen instead of destroyEntry(*(apple)); you just call destroyEntry(apple);. Note that if there is no other functionality connected with destroyEntry function, it's redundant and it's better to just directly call free(apple). ",
2012-06-17T12:16:04
Oliver Charlesworth :
Whenever you pass a parameter to a function, a copy is made, and the function works on that copy. So in your case, you are trying to free a copy of the original object, which doesn't make any sense.\n\nYou should modify your function to take a pointer, and then you can have it call free directly on that pointer.",
2012-06-17T12:14:41