Reputation: 161
I couldn't find what the behaviour of this action actually is.
It doesn't seem to cause any run-time errors so I guess it just does nothing?
I found about this technique only recently while I was writing my coursework.
Actually, my professor seems to be an advocate of this but I fail to grasp how it works without breaking.
Basically, the idea is to use a variable as a test object or guard for a struct pointer, and then pass this "dummy" variable to a function.
I'll try giving an example with code:
#include <stdio.h>
#include <stdlib.h>
struct Struct {
int a;
struct Struct *next;
float c;
};
int
stuff(struct Struct *ptr) {
free(ptr);
return 1; // always assume true for the sake of example
}
int
main(int argc, char *argv[]) {
struct Struct *ptr;
struct Struct test;
int retval;
if ((ptr = malloc(sizeof(struct Struct *))) == NULL) {
fprintf(stderr, "ERROR: could not allocate memory\n");
return -1;
}
// some magic goes here...
test = *ptr;
retval = stuff(&test);
if (retval) {
free(ptr);
}
return 0;
}
In my coursework I had to free a struct's two struct pointer members one after another, and then free the struct's memory. Since either of the struct pointer members could be operating on data, if one could not be freed then the whole main struct should not be freed and changes should be reverted.
This approach of a variable on the stack to work out whether memory can be safely freed without compromising running data is what's baffling me. I'm not really sure what I'm even not understanding.
Would anyone aware of this methodology enlighten me on the details?
Upvotes: 2
Views: 19404
Reputation: 2182
I ran this test and got a core dump. Ubuntu Linux with gcc 4.6.3. I tried several other variations on the theme and core dumped all of them.
Here is the description of free from the Linux man page:
The free() function frees the memory space pointed to by ptr, which must have been returned by a previous call to malloc(), calloc() or realloc(). Otherwise, or if free(ptr) has already been called before, undefined behavior occurs. If ptr is NULL, no operation is performed.
That word undefined is key. That means that it will not necessarily crash. Those are the worst kind of errors to debug - you are much better having a bug that crashes reliably every time. This may be safe for some configurations of compiler and libraries, but it is not for all of them. The method is best avoided.
Upvotes: 4
Reputation: 124642
couldn't find what the behaviour of [using free() on non-heap objects in C] action actually is.
It's undefined behavior. That's it, you can't make any assumptions about what will occur. test
is a copy of the memory at *ptr
. Calling free
on a pointer which was not returned by malloc
(and friends) results in undefined behavior.
Either you misunderstood your professor, or your professor doesn't know what s/he is talking about. All you need do is to read the documentation:
The behavior is undefined if ptr does not match a pointer returned earlier by malloc(), calloc() or realloc(). Also, the behavior is undefined if the memory area referred to by ptr has already been deallocated, that is, free() or realloc() has already been called with ptr as the argument and no calls to malloc(), calloc() or realloc() resulted in a pointer equal to ptr afterwards.
It doesn't seem to cause any run-time errors so I guess it just does nothing?
Welcome to C :). You're used to languages which smack your hand right away when you do something terribly wrong. C doesn't really care what you do. C gives you freedom, but that freedom works both ways (i.e., you're free to shoot your foot off as well).
Upvotes: 4