Why do I have to use free on a pointer but not a normal declaration?

前端 未结 8 1225
既然无缘
既然无缘 2021-02-13 20:07

Why do I have to use free() when I declare a pointer such as:

int *temp = (int*)malloc(sizeof(int))
*temp = 3;

but not when I do:



        
8条回答
  •  北海茫月
    2021-02-13 20:42

    It should be noted that C has no concept of stack or heap, although the preceding answers are correct ~99% of the time and give great insight.

    C defines three storage durations for objects: static, automatic and allocated. (§6.2.4.1)

    Static objects (such as global variables) are available for the duration of an entire program.

    Automatic objects exist as long as their variable is in scope. They cease to exist as soon as it goes out of scope.

    Note that these are the two extremes. C gives you a point in between: Allocated objects. (The search term would be dynamically allocated memory.) With those, you tell the computer when objects should start and end their existence. And this is done by using the standard functions malloc() (or derivatives) and free().

    Strictly speaking, you do not have to call free(). Or maybe you do (you'd have to read the standard for an authoritive point on this), but you could do it all at the end of main(), just before the program terminates. Or, leave it to the operating system to do it for you (which most, if not all, do.) But that would again be an extremity - objects come into existence when you call malloc(), go out when your program terminates.

    I should not have to talk in detail about the practical implications here: Memory is finite. You can only allocate so many bytes before you run out of memory. Using static objects for everything would be too wasteful; trying to reuse chunks or one big chunk of static memory would be hard and in any case analogous to the dynamic allocation approach. Using automatic storage for long-lived objects would force you to make their scope as big as possible, roughly corresponding to those of static objects anyway.

    --

    Now, some notes:

    {
        int *temp = malloc(sizeof(int));
        *temp = 5;
        //free(temp);
    }
    

    Note that temp here is an automatic object. It will only live as long as its scope, which ends at }. The object it's pointing to, however, is allocated. It will exist until you call free() on its address. Since temp contains the only copy of that address, you will lose the chance to call free() once temp goes out of scope. Some memory will be permanently allocated, yet unavailable. This is called a memory leak.

    Garbage collection is another method for managing object storage. An implementation in C might look like:

    {
        int *temp = gc_malloc(sizeof(int));
        *temp = 5;
    }
    

    Where at the }, the computer would decide that the last reference, temp, to the allocated object was lost and that it would be a good idea to free it.

    It is a trade-off where you don't have to worry about free()ing objects (which is not a minor thing as simple examples might make you think), but where gc_malloc() here is more complex than a simple malloc(), and there's invisible code executing at that } where temp goes out of scope. And it is a whole different topic how the computer might decide that temp was the last reference. (Some practical solutions might involve you writing more code around "int *temp".)

提交回复
热议问题