简体   繁体   中英

free() function without malloc or calloc

quick question

Can you use the free() function without having to prior call a malloc??

ei.

void someFunc( void )
{
   char str[6] = {"Hello"};

   //some processing here ....

   free(str);
}

I get no compiling errors but Does this work or is it correct at all?

Thank you,

This is not at all correct:

  1. You cannot free a static array such as char str[6] .
  2. free() should only be called on memory you allocated (or on NULL).

When you call malloc() or any other allocation function, memory will be allocated on the heap . This is the only memory that can be freed. When you declare a static string, as you've done in your example, the string is allocated at compile time in another memory segment. The same goes for the str pointer itself which is allocated on the stack , and thus cannot be freed either.

Using free on a non-malloc'd variable will result in a Segfault generally. Example:

#include <stdlib.h>

int main()
{
  char str[6] = {"Hello"};
  free(str);
}

$ gcc test.c -o test

$ ./test

Segmentation fault

free() uses data prepended to the allocated block to manage the heap. If the memory pointed to was not allocated by a heap allocation function such as malloc() or calloc(), then the data preceeding the block will be meaningless as heap management data.

Some libraries will detect invalid heap data and yieled a runtime error, otherwise the behaviour is undefined. Often the consequences of such an error will remain unnoticed until you later attempt to allocate further memory. This can make debugging such errors very difficult.

You would not get a compiler error because it is not a syntactic error and is not detectable at compile time. The compiler has no knowledge of the semantics of library functions. All it knows is that malloc() returns a void* and that free() accepts a void*; there is no way of knowing at compile time whether the pointer refers to a dynamically allocated block because the memory is by definition allocated at runtime. Also a pointer may be modified at runtime to point to any memory type, or may be aliased - copied to another pointer and then free'd through the second pointer. You expect a lot of the compiler if you expect an error message; however some static analysis tools may be able to warn if such an error may occur, and dynamic analysis tools such as valgrind may detect the error when and if it actually occurs during testing.

No


The free(3) function takes a void * parameter, so you can pass it any sort of pointer without a compile-time error. But bad things will happen if the pointer wasn't originally returned by malloc(3) and never previously given back to free(3) .

You can't, but you don't need to. When you declare a variable inside a function as you have it is called an automatic variable because it gets deleted (freeing its memory) automatically at the end of the function.

If you want to restrict the lifetime of an automatic variable you can introduce a scope using {} like this:

void someFunc( void )
{
    // do some stiff here ...

    { // <- introduce a temporary scope

        char str[6] = {"Hello"}; // this is local to your new scope

        // some processing here ...

    } // <- your array str[] is destroyed here

    // do some more stuff here, str[] has disappeared

}

Without the extra comments for clarity:

void someFunc( void )
{
    // do some stiff here ...

    {

        char str[6] = {"Hello"};

        // some processing here ...

    }

    // do some more stuff here ...

}

Introducing a new scope inside a function is a common idiom used to clean up the broader scope of extraneous variables (a potential source of bugs) but also to leverage the power of RAII .

For example when locking a mutex to synchronize a small portion of the function's code.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM