Q1
In some open source libraries, there is a common pattern to hold a private buffer:
/* ======== in modnamemapping.c ======== */
static char *private_buffer = NULL;
const char *getname( int id ) {
if ( !private_buffer )
private_buffer = (char *) malloc( 0x100 ); // in addition, the length may not
// a compile-period-constant, or
// here is some realloc() and the
// branch does not enter only once.
snprintf( private_buffer, 0x100, "NameOf%d", id );
return private_buffer;
}
// *NO* code to free private_buffer ...
As I know, this should result a memory leak, is it ?
I know only one method to fix up this issue, to use pthread_key
and pthread_once
. But there are some embeded environments that do not have builtin implements of them, and this method looks trivial and not pretty for a non-threaded program. Is there other simple and clean choice to handle this ?
Q2
There is similar behavior in libc.
I wrote a simple test code of libc function strftime()
, which makes valgrind report some definitely lost on my OS X Mavericks
. (compiler apple-gcc42
ver 4.2.1-5666.3 in brew
)
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main( void ) {
char buf[0x40], *fmt = "%x %X";
time_t t1 = time( NULL );
struct tm t2;
int ret;
(void) localtime_r( &t1, &t2 );
ret = strftime( buf, sizeof(buf), fmt, &t2 );
printf( "strftime('%s', <now>) = %d: [%s]\n", fmt, ret, buf );
return 0;
}
one of the definitely lost:
==46746== 2,242 (16 direct, 2,226 indirect) bytes in 1 blocks are definitely lost in loss record 83 of 87
==46746== at 0x70AB: malloc (in /usr/local/Cellar/valgrind/HEAD/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==46746== by 0x334FE6: _nc_table_new (in /usr/lib/system/libsystem_notify.dylib)
==46746== by 0x334A63: __token_table_add_block_invoke (in /usr/lib/system/libsystem_notify.dylib)
==46746== by 0xB62AC: _dispatch_client_callout (in /usr/lib/system/libdispatch.dylib)
==46746== by 0xB621B: dispatch_once_f (in /usr/lib/system/libdispatch.dylib)
==46746== by 0x3328A6: token_table_add (in /usr/lib/system/libsystem_notify.dylib)
==46746== by 0x3326B2: notify_register_check (in /usr/lib/system/libsystem_notify.dylib)
==46746== by 0x196AB5: notify_register_tz (in /usr/lib/system/libsystem_c.dylib)
==46746== by 0x1965EA: tzsetwall_basic (in /usr/lib/system/libsystem_c.dylib)
==46746== by 0x1967A7: _st_tzset_basic (in /usr/lib/system/libsystem_c.dylib)
==46746== by 0x198FAE: strftime_l (in /usr/lib/system/libsystem_c.dylib)
==46746== by 0x100000EB2: main (strftime.c:10)
and summary:
==46746== LEAK SUMMARY:
==46746== definitely lost: 32 bytes in 2 blocks
==46746== indirectly lost: 4,298 bytes in 7 blocks
==46746== possibly lost: 10,808 bytes in 1 blocks
==46746== still reachable: 16,384 bytes in 1 blocks
==46746== suppressed: 25,272 bytes in 375 blocks
Is there a cleanup-strftime function in libc should be called before program quit ? Or a new patch of libc about it ?