Chris Chris - 1 month ago 5
C Question

struct passwd is source of memory leak - how to properly free?

Isolated a 5 block memory leak to the use of "struct passwd". Tried several different free(user) calls to no avail. How is this struct meant to be freed? Several different SO questions on the topic, but I'm finding little documentation on how this particular struct should be handled. Program works without issue otherwise. Thanks.

#include <assert.h>
#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>

int main() {
pid_t pid = getpid();
uid_t uid = getuid();
struct passwd *user = getpwuid(uid);
unsigned int bufferMaxLen = strlen(".dir.") + strlen(user->pw_name) + 10;
char* dirName = malloc(bufferMaxLen * sizeof(char));
assert(dirName != NULL);
sprintf(dirName, "%s.dir.%d", user->pw_name, pid);

printf("bufferMaxLen is: %d\n", bufferMaxLen);
printf("Directory name is: %s\n", dirName);

free(dirName);
return 0;
}

Answer

With that code, it looks like implementation specific library feature. It's quite normal that libraries allocate memory when you first call a function, and never free it: There's no way or opportunity to free it during normal execution, and it would be totally pointless to free single memory allocations at exit handler, when they are about to be freed by program exit right after.

You can think of this kind of allocations as static data, except they're only static pointers to buffer/struct allocated only when needed. Benefit is, less memory is used if the relevant function is never called. Downside is slightly more complex code, runtime cost and memory use if the function does get called, not to mention memory analyzer confusion, demonstrated by your question :-).

Tools like Valgrind have ignore filters for hiding this kind of "leaks".

Comments