I have the following C++ file, pwd01.cpp:
#include <pwd.h>
#include <iostream>
int main() {
passwd* pwd = getpwuid(getuid());
}
I compile this with the following command:
g++ pwd01.cpp -Wall -o pwd01
On Ubuntu 12.04.1 LTS / gcc version 4.6.3, valgrind reports a leak (see below). When I compile the same code with the same command on Mac OS 10.6.8 / gcc version 4.2.1, valgrind reports no leaks.
I am aware that I do not need to free passwd* ( should I free pointer returned by getpwuid() in Linux? ); so what am I missing?
valgrind ./pwd01
==10618== Memcheck, a memory error detector
==10618== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==10618== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==10618== Command: ./pwd01
==10618==
==10618==
==10618== HEAP SUMMARY:
==10618== in use at exit: 300 bytes in 11 blocks
==10618== total heap usage: 68 allocs, 57 frees, 10,130 bytes allocated
==10618==
==10618== LEAK SUMMARY:
==10618== definitely lost: 60 bytes in 1 blocks
==10618== indirectly lost: 240 bytes in 10 blocks
==10618== possibly lost: 0 bytes in 0 blocks
==10618== still reachable: 0 bytes in 0 blocks
==10618== suppressed: 0 bytes in 0 blocks
==10618== Rerun with --leak-check=full to see details of leaked memory
==10618==
==10618== For counts of detected and suppressed errors, rerun with: -v
==10618== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)
Does not seem to be a "real" leak, i.e., if called several times, the leak doesn't compound; probably it holds a static pointer to a memory area, if it is NULL (the first time) it allocates those 60 bytes, and then doesn't free them up.
The MacOS X version either uses a truly static area, or its
valgrind
has got better suppressors.Just run the
getpwuid
a couple hundred times in a loop to ensure it really leaks only 60 bytes (and not 1200), just to be sure.UPDATE
I have finally tracked the leak to several structures inside
nssswitch.c
andgetXXent.c
, of different sizes and persuasions. While the code seems to make many more allocations than really necessary, needing malloc locks, this shouldn't be usually appreciable performance-wise, and I for one surely do not intend to second-guess the maintainers of glibc!