does free() follow pointers?

2019-06-18 16:58发布

问题:

I'm sure it doesn't, but maybe there's black magic in it, so here's my question:

If I have a struct like this:

struct mystr {
    char * strp,
    unsigned int foo,
};

and I allocate memory for it and want to release it later. Do I have to do

free(mystr_var->strp);
free(mystr_var);

or is the last line enought, does the free() function follow the pointers and free them two?

回答1:

Every individually allocated block of memory must be freed individually. free() will only free the memory block that the pointer points to and its has no knowledge of what is the content of that memory.

Hence, in your case you are doing it the right way by first freeing the innermost memory allocated in a structure and finally freeing the struct pointer.

If you just do free on the struct pointer, the struct memory gets freed. The memory held by char* strp, becomes a memory leak in your program lifetime.



回答2:

No, free doesn't follow pointers, you need both lines.

I usually write a function like:

void freemystr(mystr *mystr_var)
{
    if (mystr_var)
    {
        free(mystr_var->strp);
        mystr_var->strp = NULL;
        free(mystr_var);
    }
}


回答3:

No, it doesn't.

It's not magic at all, to the compiler it's just another function call.

Ask youself how you would implement void free(void *); in a way that follows pointers, of course without being fooled by being given a binary data block containing anything. You can't.



回答4:

No. It simply frees the block pointed to.

You need to explictly free referenced memory. You need to do this first (i.e. most likely in the opposite direction to how you allocated the memory)



回答5:

No. free won't do recursive free for all members. You have to explicitly free all members for which you have allocated memory.

If you understand how memory is allocated for struct and how free works this won't be a problem.

struct mystr {
    char * strp,
    unsigned int foo,
};

when you allocated memory using malloc & friends, it only allocates memory for the members. In your case one char* and one unsigned int. Note that it doesn't allocate any memory for storing data in the char*. So you have to allocate memory for strp again before storing data. Except when you directly assign string literals Or just use the pointer strp to point to an existing memory.

Example:

case 1:

struct mystr s;

s.strp = "literals"; // valid, no need to malloc

case 2:

char *p="abc";

s.strp = p; // valid, no need to malloc

On all other usages, you must allocate memory for strp before storing data into strp.

So when you call free on the struct variable, it only frees the pointer allocated for strp and not the memory which is pointed to by strp. It's simply because free has no information about where strp points to.

Note that in the above two examples, you don't free strp as you didn't allocate any memory there for storing data into strp. Simple rule is one free for one malloc/calloc/realloc.



回答6:

C99 says,

The free function causes the space pointed to by ptr to be deallocated, that is, made available for further allocation. If ptr is a null pointer, no action occurs. Otherwise, if the argument does not match a pointer earlier returned by the calloc, malloc, or realloc function, or if the space has been deallocated by a call to free or realloc, the behavior is undefined.