Function free() in C isn't working for me

前端 未结 5 659
无人共我
无人共我 2020-12-18 17:25

I have been trying to free memory allocated via malloc() using free().

Some of the structs it does free but leaves some the way they were a

相关标签:
5条回答
  • 2020-12-18 17:53

    First, free does not change the pointer itself.

    void *x = malloc(1);
    free(x);
    assert(x != NULL); // x will NOT return to NULL
    

    If you want the pointer to go back to NULL, you must do this yourself.

    Second, there are no guarentees about what will happen to the memory pointed to by the pointer after the free:

    int *x = malloc(sizeof(int));
    *x = 42;
    free(x);
    // The vlaue of *x is undefined; it may be 42, it may be 0,
    // it may crash if you touch it, it may do something even worse!
    

    Note that this means that you cannot actually test if free() works. Strictly speaking, it's legal for free() to be implemented by doing absolutely nothing (although you'll run out of memory eventually if this is the case, of course).

    0 讨论(0)
  • 2020-12-18 17:54

    That check won't check if the variable is freed. Note that free(pointer) does not set that pointer to NULL. If you want that to be the case, you have to set it yourself, and it is a common idiom in C:

    free(pointer);
    pointer = NULL;
    

    to signal that you already freed that pointer.

    0 讨论(0)
  • 2020-12-18 18:06

    The function free takes a pointer to allocated memory, it does not however set that pointer to NULL, in fact there is no way it could do so (it would need to take the address of a pointer for that).

    Typical use case in this scenario is:

    free(myptr);
    myptr = NULL;
    
    0 讨论(0)
  • 2020-12-18 18:16

    Calling free does not set the pointer to NULL. You have to do that yourself.

    7.21:  Why isn't a pointer null after calling free()?
        How unsafe is it to use (assign, compare) a pointer value after
        it's been freed?
    
    A:  When you call free(), the memory pointed to by the passed
        pointer is freed, but the value of the pointer in the caller
        probably remains unchanged, because C's pass-by-value semantics
        mean that called functions never permanently change the values
        of their arguments.  (See also question 4.8.)
    
        A pointer value which has been freed is, strictly speaking,
        invalid, and *any* use of it, even if it is not dereferenced,
        can theoretically lead to trouble, though as a quality of
        implementation issue, most implementations will probably not go
        out of their way to generate exceptions for innocuous uses of
        invalid pointers.
    
        References: ISO Sec. 7.10.3; Rationale Sec. 3.2.2.3.
    0 讨论(0)
  • 2020-12-18 18:17

    The only reason free() would fail is if the pointer you give it does not dereference to allocated heap. This behavior is clearly defined, free() will either work, or your program will halt due to an access violation.

    It is good practice to re-initialize your pointers after freeing them, for just this purpose. This lets you:

    • Make sure you don't allocate on top of an already allocated pointer (thus losing the reference to the original blocks and causing a leak) (realloc() notwithstanding).

    • Make sure you don't free recently freed memory, or memory that was never allocated

    Both become easy by testing to see if the pointer is initialized (or, NULL).

    It's best to just do this manually and get in the habit of doing so. I have seen some very convoluted ways of re-implementing free() so that re-initializes the pointer automatically, like this little gem that also attempts avoid freeing memory that wasn't allocated:

    void safe_free(void **p)
    {                    
            if (*p != NULL) {
                    free(*p);
                    *p = NULL;
            }                 
    }
    

    Please, don't use that code, it will break horribly on strict platforms due to dereferencing a type punned pointer. Additionally, what if the pointer is a string literal?

    Instead, just make sure you keep track of your pointers and initialize them after freeing.

    0 讨论(0)
提交回复
热议问题