Foxy
Foxy

Reputation: 1099

When is it "allowed" not to free dynamically allocated memory?

I know, any dynamically allocated memory MUST be freed at the end of its use, with free(). However, I do have a library that provides the following function:

char *rsprintf_s(const char *format, ...);

It does the same thing as asprintf, but directly returns the string that was dynamically generated within that function. For example:

int main()
{
    char *my_str = rsprintf_s("A number: %d, a string: %s.", 42, "StackOverflow");
    printf("`rsprintf_s` result: '%s'", my_str);
    return 0;
}

Which produce the following: `rsprintf_s` result: 'A number: 42, a string: "StackOverflow"'.

I imagine there's a memory leak in this program, which would force me to do this:

int main()
{
    char *my_str = rsprintf_s("A number: %d, a string: %s.", 42, "StackOverflow");
    printf("`rsprintf_s` result: '%s'", my_str);
    free(my_str);
    return 0;
}

However, is it an idiomatic function? If it exists, is it then considered a minor problem not to free the memory in this style of case? I would like to know if such a function can be used without worrying about freeing the memory every time, although I doubt it.

Upvotes: 3

Views: 167

Answers (3)

hyde
hyde

Reputation: 62797

If you are on an operating system, where a misbehaving process can't really do much passive harm, then it is in practice fine. Active harm such as corrupting files is another thing, but leaving memory un-freed at program exit will not interact with those system APIs. So omitting memory free at program exit is, in a sense, always fine when program is running in such an operating system (such as any modern desktop OS).

From a different viewpoint, it is never fine. The reasons why include, from the top of my head:

  • It's just not very smart to intentionally write non-portable code, when you don't have to for some reason. You never know what future brings.
  • Being sloppy with memory while not being sloppy with other things, that's a difficult mindset to maintain. Just don't be sloppy with your code.
  • What is now program exit might end up being just error handling function and resuming normal operation later, and then first of all it's easy to forget to fix the memory leak, and further you may have to do a lot of refactoring, when you suddenly need to have access to the pointer to be freed in a place where previously you had just thrown it away already.
  • When they see leaks, other programmers will think poorly of the whole program, and as an extension, of the programmer who wrote it.
  • In other languages, such as C++, freeing memory is coupled with calling cleanup code such as class destructor, and those in turn may for example flush buffers and close files, and not doing that can leave corrupt files etc. Better not develop bad habits with C, which you'd need to unlearn with different language.

Upvotes: 1

John Bollinger
John Bollinger

Reputation: 180201

I know, any dynamically allocated memory MUST be freed at the end of its use, with free().

No. Not freeing has the result that less memory remains for your program to allocate for other purposes. It may (or may not) cause the program's memory footprint to be larger than it otherwise would be. In flagrant, extended, or extreme cases (as judged in an environment-dependent manner), it may mean that insufficient (virtual) memory is available to serve other applications, or to serve the leaky one itself. But none of those things mean you must free memory. You always have the alternative of accepting the consequences of not doing so.

For the most part, the minor advantages attending wanton disregard for freeing allocated memory in no way balance the negative impact on the program and on the system on which it runs, but there are cases in which it does not cause any practical problem. All major operating systems in use today release processes' allocated memory at process termination. Therefore, small leaks in short-running programs are fairly inconsequential on most systems you're likely to meet, and whether one should free memory that one needs to use until just prior to program termination is a matter of style, not practicality.

And that brings us directly to your example program.

However, is it an idiomatic function? If it exists, is it then considered a minor problem not to free the memory in this style of case?

I think you meant "if it exits". As discussed above, there is substantially no difference in practical impact on the program or system between freeing manually just before exiting the top-level call to main() on one hand, and leaving it to the OS to clean up.

I would like to know if such a function can be used without worrying about freeing the memory every time, although I doubt it.

You stand in grave danger of causing trouble for yourself and others if you neglect to free allocated memory without giving careful consideration to whether doing so will produce problems. You may under some circumstances go without freeing, but it would be foolish to do so without worrying about it, so to speak. Moreover, at your apparent level of experience, you may not yet be equipped to make good judgements in this area.

I would actually put it the other way around, then: being sure to free allocated memory when you no longer need it is the worry-free alternative. Or at least worry-less. You can make that relatively easy by cultivating programming practices that support it.

Upvotes: 3

Patrick87
Patrick87

Reputation: 28302

If you have a small program that is going to exit quickly and you are running on a fully-featured modern desktop or server operating system, then probably you can rely on the operating system to clean up allocated heap memory when the process terminates; see here.

Unless rsprintf_s specifically tells you that you should free what it returns, I would not assume this is the case. It is possible that it has an implementation which does not even use heap memory (perhaps it uses statically allocated global memory, perhaps in a DATA section or something).

Upvotes: 4

Related Questions