以下代码是我连接服务器的 C 程序的摘录:
struct addrinfo hints, *res, *matchingIP;
char addrstr[99];
char port[20];
snprintf(port, sizeof(port), "%d", PORTNUMBER); // PORTNUMBER as char*
int sock;
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = 0;
hints.ai_flags = AI_CANONNAME;
int status = getaddrinfo(HOSTNAME, port, &hints, &matchingIP); // Memory Leak occurs here?
if (status < 0)
{
perror("No IP address found.");
}
for (res = matchingIP; res != NULL; res = res->ai_next)
{
sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
if (sock < 0)
{
perror("No socket created.");
continue;
}
if (connect(sock, res->ai_addr, res->ai_addrlen) < 0)
{
perror("Client not connected.");
continue;
}
break;
}
if (res == NULL)
{
perror("Client could not connect.");
return EXIT_FAILURE;
}
inet_ntop(res->ai_family, &((struct sockaddr_in *)res->ai_addr)->sin_addr, addrstr, sizeof addrstr);
printf("IPv4 address: %s (%s)\n", addrstr, res->ai_canonname);
freeaddrinfo(matchingIP);
现在,当我运行 valgrind 时,它显示存在“仍然可访问”的内存,我已将其范围缩小到
getaddrinfo
调用(之前没有出现泄漏)。这是完整的 valgrind 日志:
==566543== HEAP SUMMARY:
==566543== in use at exit: 3,509 bytes in 8 blocks
==566543== total heap usage: 112 allocs, 104 frees, 112,649 bytes allocated
==566543==
==566543== 38 bytes in 1 blocks are still reachable in loss record 1 of 7
==566543== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==566543== by 0x401F5DE: strdup (strdup.c:42)
==566543== by 0x4019A91: _dl_load_cache_lookup (dl-cache.c:338)
==566543== by 0x400A989: _dl_map_object (dl-load.c:2102)
==566543== by 0x400F514: openaux (dl-deps.c:64)
==566543== by 0x4A17B47: _dl_catch_exception (dl-error-skeleton.c:208)
==566543== by 0x400F962: _dl_map_object_deps (dl-deps.c:248)
==566543== by 0x4015DAF: dl_open_worker (dl-open.c:571)
==566543== by 0x4A17B47: _dl_catch_exception (dl-error-skeleton.c:208)
==566543== by 0x4015609: _dl_open (dl-open.c:837)
==566543== by 0x4A16AE0: do_dlopen (dl-libc.c:96)
==566543== by 0x4A17B47: _dl_catch_exception (dl-error-skeleton.c:208)
==566543==
==566543== 38 bytes in 1 blocks are still reachable in loss record 2 of 7
==566543== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==566543== by 0x400D5B7: _dl_new_object (dl-object.c:196)
==566543== by 0x4006E96: _dl_map_object_from_fd (dl-load.c:997)
==566543== by 0x400A61A: _dl_map_object (dl-load.c:2236)
==566543== by 0x400F514: openaux (dl-deps.c:64)
==566543== by 0x4A17B47: _dl_catch_exception (dl-error-skeleton.c:208)
==566543== by 0x400F962: _dl_map_object_deps (dl-deps.c:248)
==566543== by 0x4015DAF: dl_open_worker (dl-open.c:571)
==566543== by 0x4A17B47: _dl_catch_exception (dl-error-skeleton.c:208)
==566543== by 0x4015609: _dl_open (dl-open.c:837)
==566543== by 0x4A16AE0: do_dlopen (dl-libc.c:96)
==566543== by 0x4A17B47: _dl_catch_exception (dl-error-skeleton.c:208)
==566543==
==566543== 45 bytes in 1 blocks are still reachable in loss record 3 of 7
==566543== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==566543== by 0x401F5DE: strdup (strdup.c:42)
==566543== by 0x4019A91: _dl_load_cache_lookup (dl-cache.c:338)
==566543== by 0x400A989: _dl_map_object (dl-load.c:2102)
==566543== by 0x4015D46: dl_open_worker (dl-open.c:513)
==566543== by 0x4A17B47: _dl_catch_exception (dl-error-skeleton.c:208)
==566543== by 0x4015609: _dl_open (dl-open.c:837)
==566543== by 0x4A16AE0: do_dlopen (dl-libc.c:96)
==566543== by 0x4A17B47: _dl_catch_exception (dl-error-skeleton.c:208)
==566543== by 0x4A17C12: _dl_catch_error (dl-error-skeleton.c:227)
==566543== by 0x4A16C14: dlerror_run (dl-libc.c:46)
==566543== by 0x4A16C14: __libc_dlopen_mode (dl-libc.c:195)
==566543== by 0x49FA8CB: nss_load_library (nsswitch.c:359)
==566543==
==566543== 45 bytes in 1 blocks are still reachable in loss record 4 of 7
==566543== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==566543== by 0x400D5B7: _dl_new_object (dl-object.c:196)
==566543== by 0x4006E96: _dl_map_object_from_fd (dl-load.c:997)
==566543== by 0x400A61A: _dl_map_object (dl-load.c:2236)
==566543== by 0x4015D46: dl_open_worker (dl-open.c:513)
==566543== by 0x4A17B47: _dl_catch_exception (dl-error-skeleton.c:208)
==566543== by 0x4015609: _dl_open (dl-open.c:837)
==566543== by 0x4A16AE0: do_dlopen (dl-libc.c:96)
==566543== by 0x4A17B47: _dl_catch_exception (dl-error-skeleton.c:208)
==566543== by 0x4A17C12: _dl_catch_error (dl-error-skeleton.c:227)
==566543== by 0x4A16C14: dlerror_run (dl-libc.c:46)
==566543== by 0x4A16C14: __libc_dlopen_mode (dl-libc.c:195)
==566543== by 0x49FA8CB: nss_load_library (nsswitch.c:359)
==566543==
==566543== 936 bytes in 2 blocks are still reachable in loss record 5 of 7
==566543== at 0x483DD99: calloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==566543== by 0x401331C: _dl_check_map_versions (dl-version.c:274)
==566543== by 0x40160FC: dl_open_worker (dl-open.c:577)
==566543== by 0x4A17B47: _dl_catch_exception (dl-error-skeleton.c:208)
==566543== by 0x4015609: _dl_open (dl-open.c:837)
==566543== by 0x4A16AE0: do_dlopen (dl-libc.c:96)
==566543== by 0x4A17B47: _dl_catch_exception (dl-error-skeleton.c:208)
==566543== by 0x4A17C12: _dl_catch_error (dl-error-skeleton.c:227)
==566543== by 0x4A16C14: dlerror_run (dl-libc.c:46)
==566543== by 0x4A16C14: __libc_dlopen_mode (dl-libc.c:195)
==566543== by 0x49FA8CB: nss_load_library (nsswitch.c:359)
==566543== by 0x49FB178: __nss_lookup_function (nsswitch.c:467)
==566543== by 0x49BB4BE: gaih_inet.constprop.0 (getaddrinfo.c:800)
==566543==
==566543== 1,200 bytes in 1 blocks are still reachable in loss record 6 of 7
==566543== at 0x483DD99: calloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==566543== by 0x400D283: _dl_new_object (dl-object.c:89)
==566543== by 0x4006E96: _dl_map_object_from_fd (dl-load.c:997)
==566543== by 0x400A61A: _dl_map_object (dl-load.c:2236)
==566543== by 0x400F514: openaux (dl-deps.c:64)
==566543== by 0x4A17B47: _dl_catch_exception (dl-error-skeleton.c:208)
==566543== by 0x400F962: _dl_map_object_deps (dl-deps.c:248)
==566543== by 0x4015DAF: dl_open_worker (dl-open.c:571)
==566543== by 0x4A17B47: _dl_catch_exception (dl-error-skeleton.c:208)
==566543== by 0x4015609: _dl_open (dl-open.c:837)
==566543== by 0x4A16AE0: do_dlopen (dl-libc.c:96)
==566543== by 0x4A17B47: _dl_catch_exception (dl-error-skeleton.c:208)
==566543==
==566543== 1,207 bytes in 1 blocks are still reachable in loss record 7 of 7
==566543== at 0x483DD99: calloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==566543== by 0x400D283: _dl_new_object (dl-object.c:89)
==566543== by 0x4006E96: _dl_map_object_from_fd (dl-load.c:997)
==566543== by 0x400A61A: _dl_map_object (dl-load.c:2236)
==566543== by 0x4015D46: dl_open_worker (dl-open.c:513)
==566543== by 0x4A17B47: _dl_catch_exception (dl-error-skeleton.c:208)
==566543== by 0x4015609: _dl_open (dl-open.c:837)
==566543== by 0x4A16AE0: do_dlopen (dl-libc.c:96)
==566543== by 0x4A17B47: _dl_catch_exception (dl-error-skeleton.c:208)
==566543== by 0x4A17C12: _dl_catch_error (dl-error-skeleton.c:227)
==566543== by 0x4A16C14: dlerror_run (dl-libc.c:46)
==566543== by 0x4A16C14: __libc_dlopen_mode (dl-libc.c:195)
==566543== by 0x49FA8CB: nss_load_library (nsswitch.c:359)
==566543==
==566543== LEAK SUMMARY:
==566543== definitely lost: 0 bytes in 0 blocks
==566543== indirectly lost: 0 bytes in 0 blocks
==566543== possibly lost: 0 bytes in 0 blocks
==566543== still reachable: 3,509 bytes in 8 blocks
==566543== suppressed: 0 bytes in 0 blocks
==566543==
==566543== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
我在网上读过好几次,虽然“仍然可达”的内存泄漏是内存泄漏,但它们不是我应该担心的。对我来说不幸的是,这是一个正式要求,valgrind 报告绝对没有内存泄漏,包括仍然可达。我有机会修复它还是图书馆的错?如果是后者 - 什么是合适的替代方案? 据我所知,主机使用 IPv6 运行 - 也许这是相关的。
编辑:该项目使用
-std=c99
标志进行编译,并将 posix C 源定义为 #define _POSIX_C_SOURCE 200809L
。
它泄漏是因为你用完后没有释放
matchingIP
:
freeaddrinfo(matchingIP);