2

Which strings ought I to free in C on my own, using free()¹?

My state of knowledge:

  • char a[256];: no
  • char *a = "abcdefg";: no
  • char *a = malloc(15L);: yes
  • a string returned by getenv(): no
  • strings returned by Windows functions²: ???

¹ or LocalFree()/GlobalFree()/VirtualFree()
² in particular by GetCommandLineW()

Toby Speight
  • 27,591
  • 48
  • 66
  • 103
7vujy0f0hy
  • 8,741
  • 1
  • 28
  • 33
  • From [the man](https://linux.die.net/man/3/malloc): _The **free()** function frees the memory space pointed to by ptr, which must have been returned by a previous call to **malloc()**, **calloc()** or **realloc()**. Otherwise, or if free(ptr) has already been called before, undefined behavior occurs. If ptr is NULL, no operation is performed._ – LPs Apr 03 '17 at 15:02
  • @LPs: As usual, `man` delivers incomplete answers. For example, the string returned by `getenv()` is obtained by a `malloc()` call executed internally by that function. And yet the user is not supposed to free that string... – 7vujy0f0hy Apr 03 '17 at 15:09
  • But [notes in man](http://man7.org/linux/man-pages/man3/getenv.3.html): _As typically implemented, getenv() returns a pointer to a string within the environment list. The caller must take care not to modify this string, since that would change the environment of the process_ ... so man has answers.... – LPs Apr 03 '17 at 15:13
  • @LPs: When it does... they contradict each other. Like in this case. – 7vujy0f0hy Apr 03 '17 at 15:14
  • Where the manual state that the returned string is `malloc`ated? – LPs Apr 03 '17 at 15:15
  • @LPs: You could ask the same question about new strings returned by *any* function... Should I always presume they are not `malloc`ated unless documentation says they are? – 7vujy0f0hy Apr 03 '17 at 15:22
  • 2
    If the function that return a string gave you something to **free()** its documentation must state that. BTW tons of poor documentation exist. If you have no info you cannot assume that as string returned by a function is `malloc`ated. – LPs Apr 03 '17 at 15:24
  • @LPs: I think I get it. Now the MSDN page for `GetCommandLineW()` doesn’t mention the issue. Should I assume that it requires no `free()` action on user’s part? Or must I read whole MSDN first to make sure? – 7vujy0f0hy Apr 03 '17 at 15:28
  • @LPs: Partial success: I have found some indirect hint on the MSDN documentation page for another (closely related) function `CommandLineToArgvW()` – in form of [an example code](https://msdn.microsoft.com/en-us/library/windows/desktop/bb776391(v=vs.85).aspx). Sadly, the way that code handles this issue reveals **a double standard:** it does `LocalFree()` for the array of pointers (`argv`) returned by that function *but not* for the strings referred to by those pointers... – 7vujy0f0hy Apr 03 '17 at 15:51
  • 1
    @7vujy0f0hy there is no inherent contradiction in freeing the array containing the string pointers, but not the pointed-to strings. The documentation specifies how to free the memory allocated by that function, and the example demonstrates it. Apparently, the function allocates all the memory needed for the array and the individual strings in one block. – John Bollinger Apr 03 '17 at 16:17
  • @JohnBollinger: You’re right. “`CommandLineToArgvW` allocates a block of **contiguous** memory for pointers to the argument strings, *and* for the argument strings themselves.” – 7vujy0f0hy Apr 03 '17 at 16:23

3 Answers3

3

This will always be mentioned in the documentation for any API you use that returns strings (or other data larger than a single simple value such as an integer).

Yes, this means you have to read the documentation thoroughly for all such API functions, in order to keep track and not leak memory.

unwind
  • 391,730
  • 64
  • 469
  • 606
  • 2
    @7vujy0f0hy, sure you are. But you are unwise to use `GetCommandLineW()` without reading ***that function***'s documentation carefully. In the event that the function's documentation does not specify a responsibility to free the returned string, it is usually best to assume that you should not free it. The memory leak resulting from failing to free a dynamically-allocated string is likely to be less impactful than the result of attempting to free memory that you are not supposed to free. – John Bollinger Apr 03 '17 at 16:02
  • @JohnBollinger: Not only have I read `GetCommandLineW()` quite thoroughly, I have digged up [an example code](https://msdn.microsoft.com/en-us/library/windows/desktop/bb776391(v=vs.85).aspx) involving it (in my other comment) – the only “mention” (if oblique) of this question in the documentation. Sadly, that example appears to contradict itself: it frees an array of pointers to strings returned by another Windows API function but it doesn’t free the strings themselves... – 7vujy0f0hy Apr 03 '17 at 16:03
  • 1
    @7vujy0f0hy, I'm inclined to agree that the example code (for a different function) in the documentation you linked appears to leak memory, given that one believes the prose of that doc (as one should). On the other hand, I note that that doc *does* express just the sort of responsibility to free that I described. If no such responsibility is documented for the function in which you are actually interested, then, as I already said, you should assume that you are not responsible for freeing. – John Bollinger Apr 03 '17 at 16:13
  • @JohnBollinger: I feel free at last! Thank you ☺. – 7vujy0f0hy Apr 03 '17 at 16:15
2

The only chunks of memory that must be freed are those that were previously malloced.

Now the questions are "is this pointer a pointer to memory that was created by malloc ?" and, if so, "am I supposed to free it myself or will some other function take care of it ?"

There are no easy answers to these questions, generally the documentation will tell you so, but the rule of thumb is that the module that takes care of memory creation also takes care of deallocation. So, if the library you use expects you to provide already allocated memory, you are supposed to free it, too, when needed.

Fabien
  • 12,486
  • 9
  • 44
  • 62
  • I can’t find any mention of this issue on the MSDN documentation page dedicated to `GetCommandLineW()`. Should I search harder or should I assume that I need not worry about freeing the returned string? – 7vujy0f0hy Apr 03 '17 at 15:40
1

In case of explicit dynamic allocation i.e. malloc/alloc/realloc you have to explicitly free it. But now that you have mentioned about strings there is a special function strdup() which under-the-hood malloc for you when you call it.

In case of strdup(), you have to make sure that without you allocating you MUST free it.

Milind Deore
  • 2,887
  • 5
  • 25
  • 40