开发者

Does every malloc call have to be freed

From what I understand because malloc dynamically assigns mem , you need to free that mem so that it can be used again.

  1. What happens if you return a char* that was created using malloc (i.e. how are you supposed to free that)
  2. If you leave the pointer as i开发者_C百科t is and exit the application will it be freed.(I cant find a definite answer on this , some say yes , some say no).


  1. The caller has to free it (or arrange for it to be freed). This means that functions that create and return resources need to document exactly how it should be freed.

  2. Most OSes will free the memory when the program exits, as part of the definition of a "process". The C standard doesn't care what happens, it's beyond the scope of the program. Not all OSes have a full process abstraction, but desktop-style OSes certainly do.

The main reasons to free it before that are:

  • If you free memory as soon as possible, often a long time before process exit, your program uses less memory total.
  • If you don't free it, and you later want to change your program into a routine within another program, that perhaps is called many times, then suddenly you require many times as much memory as before (memory leak).
  • There are debugging tools that will help you identify memory leaks, by warning you about memory that is still allocated when the program exits. These don't really help much if there's a lot of deliberately-leaked junk to wade through.
  • If you don't free it and you hit any problems, it's much harder to go back later and find all the memory that needs freeing, than it is to do it right in the first place.
  • There are so many cases where you do need to free the memory (to prevent huge memory use in long-running programs), that your default strategy must be to clean pretty much everything up anyway.

The vaguely plausible reasons not to free are:

  • Less code.
  • If you have squillions of blocks to free individually, immediately before program exit, then it might be much faster to let the OS drop the whole process.
  • Stuff which is created on demand and stored in globals might be quite difficult to clean up safely, if you don't know exactly where it's used. Think of some kind of cache that's populated as you go along, that might have MRU rules to limit how much memory it occupies, so it's not an unlimited leak. OK, so this is one bad thing (unrestricted globals) causing another bad thing (unfreed memory), but it's worth knowing about as a reason why you might see unfreed blocks in existing code, and you can't necessarily just go in and fix them.

The reasons for freeing almost always outweigh the reasons against.


  1. If you have a pointer to memory created by malloc, freeing that memory, using that pointer, will do the right thing. Yes, there is some magic involved; this will be taken care of by your compiler.

  2. Yes, if you ignore the memory freeing, and exit the application, the OS will release the memory. However, it's considered bad practice to leave it unfreed. The OS may not do the right thing (especially in embedded settings), or may not do it in a timely fashion. Also, if you're running your program continuously, you may end up consuming a growing amount of memory, eventually consuming it all, and running out of memory and crashing.


Yes. If you malloc, you need to free. You are guaranteeing memory leaks while your program is running if you don't free.

Free it.

Always.

Period.


Yes, every call to malloc() has to be matched with a call to free().

To answer your specific questions:

  1. You have to explicitly document your API telling the user whether the returned pointer has to be free()'d
  2. The OS will free all memory allocated to the process.


If you write the function yourself: Avoid doing that.

  • Instead, let the caller pass a buffer, let the caller specify the buffer's size and copy the data into that buffer. That way, you can use your function from other modules that don't use the same heap (other programming languages, different C runtime...)
  • If you for whatever reason can not use such an interface, specify in the function's documentation that the caller has to free the returned pointer after it is done with it.

If you are using a library function: Have a look at the documentation.

  • If the documentation states that you have to free, do so.
  • If the documentation states that you don't have to, it might be some global cleanup function that has to be called to free the module's resources.

Regarding your second question, freeing before exiting is recommended. Technically it wont hurt, but when you ever want to reuse your code in a bigger project, you will be thankful that you wrote the correct cleanup in the first place.


The C standard has no concept of the system environment outside of a single program's execution, so it cannot specify what happens "after the program exits". At the same time, nowhere does it make any requirement that memory obtained with malloc should or must be released with free before a call to exit or a return from main, and I think it's pretty clear that the intention is that exiting without manually freeing memory will not leave resources tied up - much like how calling exit without closing all files first automatically closes them (including flushing them).

Now, as for whether you should or should not call free, that depends a lot on your particular program.

  • Any library code should free any memory that it obtained purely for internal use as soon as possible.
  • A library which returns allocated objects to the calling program should always provide a corresponding call to free those objects.
  • A library which performs any allocations as part of a global initialization (note: this is a very bad design, but sometimes inevitable) should provide a way for the application to reverse that initialization and free everything that was allocated. This is especially important if the library might ever be loaded dynamically (even as a consequence of satisfying another dynamically-loaded library's dependencies).

So far I've only talked about library code. At this point, all that's left is allocations made by the application itself or on the application's behalf by libraries. My view, and I will admit that it is unorthodox, is that freeing such objects is not just unnecessary but harmful. The main reason I say this is that most long-lived applications will have accumulated quite a bit of allocated memory which they are not making significant use of (think of the undo buffer in a word processor or the history in a browser). On a moderately loaded system, much of this data has been swapped to disk by the time the application terminates. If you want to free it, you're going to end up walking all over swapped-out memory addresses tracking down all the pointers to free,

  • putting useless wear on the physical components of the hard drive
  • making the user wait for your application to exit
  • causing other still-in-use applications' data to get swapped out, making them run slower

All of this in the name of a ridiculous "you must free everything you allocate" rule.

For short-lived applications, it's not so much of a big deal, but you can often simplify the implementation of short-lived applications that perform a single linear task and exit if you don't bother freeing all the memory they allocate. Think of most unix command line utilities. Is there any use to writing the loops for sed to free all its compiled regular expressions before exiting? Couldn't programmers' time be spent on something more productive?


1) The same way you'd free the memory normally, i.e.

p = func();
//...
free(p);

The trick is in making sure that you always do it...

2) Generally speaking, yes. But you should still free any memory you use as good practice. Not spending the time to figure out where to free the memory is just being lazy.


Let's take those one point at a time...

  1. If you return a char * that you know was created with malloc, then yes, it is your responsibility to free that. You can do that with free(myCharPtr).

  2. The OS will claim the memory back, and it won't be lost forever, but there's technically no guarantee that it will be reclaimed right when the application dies. That just depends on the operating system.


I wouldn't go so far as to say every malloc must be freed, but I would say that, no matter how long a program runs, there must be a bounded number of allocations (and total size) that won't be freed. The number need not be a static constant, but it must be specifiable in terms of something else (e.g. this program processes widgets; it will allocate one 64-byte struct for each quizzix in the largest widget). One may not know beforehand the size of the largest widget, but if e.g. one knows that the temporary storage required to process a widget is proportional to the square of its size, one might safely infer that the largest widget will be small enough that the total amount of memory stranded will be pretty slight.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜