Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should I free the pointer returned by setlocale?

int main(int argc, char *argv[])
{
    char *ret = setlocale(LC_ALL, NULL);
    // should I free 'ret' ???
    // free(ret);
    return 0;
}

I've tried both on Linux and OS X 10.10, on Linux, I must not call 'free', but on OS X, if I do not call 'free', valgrind complains a memory leak.

==62032== Memcheck, a memory error detector
==62032== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==62032== Using Valgrind-3.11.0.SVN and LibVEX; rerun with -h for copyright info
==62032== Command: ./a.out
==62032== 
--62032-- ./a.out:
--62032-- dSYM directory is missing; consider using --dsymutil=yes
==62032== 
==62032== HEAP SUMMARY:
==62032==     in use at exit: 129,789 bytes in 436 blocks
==62032==   total heap usage: 519 allocs, 83 frees, 147,421 bytes allocated
==62032== 
==62032== 231 bytes in 1 blocks are definitely lost in loss record 63 of 91
==62032==    at 0x10000859B: malloc (in /usr/local/Cellar/valgrind/HEAD/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==62032==    by 0x1001E68C8: currentlocale (in /usr/lib/system/libsystem_c.dylib)
==62032==    by 0x100000F6B: main (in ./a.out)
==62032== 
==62032== LEAK SUMMARY:
==62032==    definitely lost: 231 bytes in 1 blocks
==62032==    indirectly lost: 0 bytes in 0 blocks
==62032==      possibly lost: 0 bytes in 0 blocks
==62032==    still reachable: 94,869 bytes in 10 blocks
==62032==         suppressed: 34,689 bytes in 425 blocks
==62032== Reachable blocks (those to which a pointer was found) are not shown.
==62032== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==62032== 
==62032== For counts of detected and suppressed errors, rerun with: -v
==62032== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 17 from 17)

So, in Linux, if I call 'free', it will crash. in OS X, if I do not call 'free', it has a memory leak.

like image 778
noinput Avatar asked Mar 18 '15 07:03

noinput


1 Answers

You should not free the string that you get. According to the C11 standard:

7.11.1.1 The setlocale function

The pointer to string returned by the setlocale function is such that a subsequent call with that string value and its associated category will restore that part of the program’s locale. The string pointed to shall not be modified by the program, but may be overwritten by a subsequent call to the setlocale function

Additionally, the Linux man pages say:

This string may be allocated in static storage.

which would result in your program crashing if you tried to free it.

It looks like the Linux implementation uses static storage, but the OSX one uses malloc. Regardless of what's going on under the hood, you should not modify it because the standard disallows you from doing so --- the fact that it would be safe on OSX is an implementation quirk you should ignore. Valgrind is essentially giving you a false positive here.

like image 81
Patrick Collins Avatar answered Oct 22 '22 07:10

Patrick Collins