为什么 libcurl 在清理调用后仍然留下可访问的块?

Why libcurl still leaves reachable blocks after cleanup calls?

我一直在使用 libcurl 来处理 get/post 请求,而 valgrind 总是向我显示相同数量的可访问块 (21)。我在标准 cURL 的配置中缺少什么来避免这种情况?

这是最简单的代码 "error":

#include <stdio.h>
#include <stdlib.h>
#include <curl/curl.h>

int main(int argc, char const *argv[]) {

  CURL *curl;

  curl_global_init(CURL_GLOBAL_ALL);
  curl = curl_easy_init();
  ·
  ·
  ·
  curl_easy_cleanup(curl);
  curl_global_cleanup();

  return 0;

}

我用

编译
$ gcc -o test cURL.c -lcurl

Valgrind 检查

$ valgrind --leak-check=full --track-origins=yes ./test

==4295== Memcheck, a memory error detector
==4295== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==4295== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==4295== Command: ./test
==4295== 
==4295== 
==4295== HEAP SUMMARY:
==4295==     in use at exit: 858 bytes in 21 blocks
==4295==   total heap usage: 4,265 allocs, 4,244 frees, 185,353 bytes allocated
==4295== 
==4295== LEAK SUMMARY:
==4295==    definitely lost: 0 bytes in 0 blocks
==4295==    indirectly lost: 0 bytes in 0 blocks
==4295==      possibly lost: 0 bytes in 0 blocks
==4295==    still reachable: 858 bytes in 21 blocks
==4295==         suppressed: 0 bytes in 0 blocks
==4295== Reachable blocks (those to which a pointer was found) are not shown.
==4295== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==4295== 
==4295== For counts of detected and suppressed errors, rerun with: -v
==4295== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

libcurl 链接到许多库,其中一些库没有像 curl_global_cleanup 这样的函数,可以恢复初始化并释放所有内存。当 libcurl 链接到 NSS 以获得 TLS 支持时,以及 libssh2 和它对 libgcrypt 的使用时,就会发生这种情况。 GNUTLS 作为 TLS 实现在这方面更简洁。

一般来说,这不是问题,因为这些辅助库仅用于在进程终止时释放内存的操作系统,因此不需要显式清理(甚至会减慢进程终止速度)。仅对于某些内存调试器,缺少清理例程的影响是可见的,而 valgrind 通过区分实际泄漏(没有指针指向的内存)和进程终止时仍可访问的内存(以便它可以有如果进程没有终止,则再次使用)。