Curl:程序运行时如何清除存储的数据

Curl:程序运行时如何清除存储的数据,c,curl,memory,free,C,Curl,Memory,Free,我用C语言编写了一个文本状态栏程序,它使用curl连接到一个天气站点,获取数据,获取正确的信息,并将其显示在状态栏中。程序的这一部分工作得很好。问题是,在程序成功连接到服务器后,下载页面并将其存储到内存中,在我提取并显示天气数据后,程序不会释放下载的内存,因此需要额外的15Mb内存才能运行,直到我关闭程序 /* Compile with: gcc -O2 -Wall mycurl.c -o mycurl -L/usr/include/curl/lib -lcurl Courtes

我用C语言编写了一个文本状态栏程序,它使用curl连接到一个天气站点,获取数据,获取正确的信息,并将其显示在状态栏中。程序的这一部分工作得很好。问题是,在程序成功连接到服务器后,下载页面并将其存储到内存中,在我提取并显示天气数据后,程序不会释放下载的内存,因此需要额外的15Mb内存才能运行,直到我关闭程序

/*

  Compile with:
  gcc -O2 -Wall mycurl.c -o mycurl -L/usr/include/curl/lib -lcurl

  Courtesy of:
  https://curl.haxx.se/libcurl/c/getinmemory.html

*/

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

struct MemoryStruct {
  char *memory;
  size_t size;
};

static size_t
WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp)
{
  size_t realsize = size * nmemb;
  struct MemoryStruct *mem = (struct MemoryStruct *)userp;

  char *ptr = realloc(mem->memory, mem->size + realsize + 1);
  if(ptr == NULL) {
    /* out of memory! */ 
    printf("not enough memory (realloc returned NULL)\n");
    return 0;
  }

  mem->memory = ptr;
  memcpy(&(mem->memory[mem->size]), contents, realsize);
  mem->size += realsize;
  mem->memory[mem->size] = 0;
  return realsize;
}

int main(void)
{
  CURL *curl;
  CURLcode res;

  struct MemoryStruct chunk;

  chunk.memory = malloc(1);
  chunk.size = 0; 

  curl_global_init(CURL_GLOBAL_ALL);

  curl = curl_easy_init();

  curl_easy_setopt(curl, CURLOPT_URL, "https://www.google.com/");
  curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
  curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);
  curl_easy_setopt(curl, CURLOPT_USERAGENT, "libcurl-agent/1.0");

  res = curl_easy_perform(curl);

/* check for errors */ 
  if(res != CURLE_OK) {
    fprintf(stderr, "curl_easy_perform() failed: %s\n",
            curl_easy_strerror(res));
    return 1;
  }

  printf("%lu bytes retrieved\n", (unsigned long)chunk.size);

  curl_easy_cleanup(curl);
  free(chunk.memory);
  curl_global_cleanup();

  /* Everything is all cleaned up, so the memory usage should be back to      normal at this point. */

  printf("Waiting 3 seconds... Watch to see if the memory levels change between now and when the program says 'Done!' If you see a change in memory, there is likely a leak.)\n");


  /* When the program shuts down, the memory is released, but it should release after we cleanup and before the program terminates. Lets give ourselves a few seconds to spot if this is the case. Make sure to have 'top' or 'htop' open and  */

  sleep(3); // top and htop default at 3 second intervals, so we need more than that to spot a change


  printf("\nDone!\nDid the memory change?\n");

  return 0;
}
这似乎是在我发布时发生的:

curl_easy_perform(curl);
/*

  Compile with:
  gcc -O2 -Wall mycurl.c -o mycurl -L/usr/include/curl/lib -lcurl

  Courtesy of:
  https://curl.haxx.se/libcurl/c/getinmemory.html

*/

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

struct MemoryStruct {
  char *memory;
  size_t size;
};

static size_t
WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp)
{
  size_t realsize = size * nmemb;
  struct MemoryStruct *mem = (struct MemoryStruct *)userp;

  char *ptr = realloc(mem->memory, mem->size + realsize + 1);
  if(ptr == NULL) {
    /* out of memory! */ 
    printf("not enough memory (realloc returned NULL)\n");
    return 0;
  }

  mem->memory = ptr;
  memcpy(&(mem->memory[mem->size]), contents, realsize);
  mem->size += realsize;
  mem->memory[mem->size] = 0;
  return realsize;
}

int main(void)
{
  CURL *curl;
  CURLcode res;

  struct MemoryStruct chunk;

  chunk.memory = malloc(1);
  chunk.size = 0; 

  curl_global_init(CURL_GLOBAL_ALL);

  curl = curl_easy_init();

  curl_easy_setopt(curl, CURLOPT_URL, "https://www.google.com/");
  curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
  curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);
  curl_easy_setopt(curl, CURLOPT_USERAGENT, "libcurl-agent/1.0");

  res = curl_easy_perform(curl);

/* check for errors */ 
  if(res != CURLE_OK) {
    fprintf(stderr, "curl_easy_perform() failed: %s\n",
            curl_easy_strerror(res));
    return 1;
  }

  printf("%lu bytes retrieved\n", (unsigned long)chunk.size);

  curl_easy_cleanup(curl);
  free(chunk.memory);
  curl_global_cleanup();

  /* Everything is all cleaned up, so the memory usage should be back to      normal at this point. */

  printf("Waiting 3 seconds... Watch to see if the memory levels change between now and when the program says 'Done!' If you see a change in memory, there is likely a leak.)\n");


  /* When the program shuts down, the memory is released, but it should release after we cleanup and before the program terminates. Lets give ourselves a few seconds to spot if this is the case. Make sure to have 'top' or 'htop' open and  */

  sleep(3); // top and htop default at 3 second intervals, so we need more than that to spot a change


  printf("\nDone!\nDid the memory change?\n");

  return 0;
}
我不知道如何在不关闭程序的情况下释放内存,我需要程序保持打开状态。我不想制作一个单独的程序并调用它,因为我希望将来在该程序中使用curl来实现其他功能(例如ping网络以检查连接),所以我最好在它存在时使用它

/*

  Compile with:
  gcc -O2 -Wall mycurl.c -o mycurl -L/usr/include/curl/lib -lcurl

  Courtesy of:
  https://curl.haxx.se/libcurl/c/getinmemory.html

*/

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

struct MemoryStruct {
  char *memory;
  size_t size;
};

static size_t
WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp)
{
  size_t realsize = size * nmemb;
  struct MemoryStruct *mem = (struct MemoryStruct *)userp;

  char *ptr = realloc(mem->memory, mem->size + realsize + 1);
  if(ptr == NULL) {
    /* out of memory! */ 
    printf("not enough memory (realloc returned NULL)\n");
    return 0;
  }

  mem->memory = ptr;
  memcpy(&(mem->memory[mem->size]), contents, realsize);
  mem->size += realsize;
  mem->memory[mem->size] = 0;
  return realsize;
}

int main(void)
{
  CURL *curl;
  CURLcode res;

  struct MemoryStruct chunk;

  chunk.memory = malloc(1);
  chunk.size = 0; 

  curl_global_init(CURL_GLOBAL_ALL);

  curl = curl_easy_init();

  curl_easy_setopt(curl, CURLOPT_URL, "https://www.google.com/");
  curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
  curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);
  curl_easy_setopt(curl, CURLOPT_USERAGENT, "libcurl-agent/1.0");

  res = curl_easy_perform(curl);

/* check for errors */ 
  if(res != CURLE_OK) {
    fprintf(stderr, "curl_easy_perform() failed: %s\n",
            curl_easy_strerror(res));
    return 1;
  }

  printf("%lu bytes retrieved\n", (unsigned long)chunk.size);

  curl_easy_cleanup(curl);
  free(chunk.memory);
  curl_global_cleanup();

  /* Everything is all cleaned up, so the memory usage should be back to      normal at this point. */

  printf("Waiting 3 seconds... Watch to see if the memory levels change between now and when the program says 'Done!' If you see a change in memory, there is likely a leak.)\n");


  /* When the program shuts down, the memory is released, but it should release after we cleanup and before the program terminates. Lets give ourselves a few seconds to spot if this is the case. Make sure to have 'top' or 'htop' open and  */

  sleep(3); // top and htop default at 3 second intervals, so we need more than that to spot a change


  printf("\nDone!\nDid the memory change?\n");

  return 0;
}
<>我在C++中完成这个工作,没有额外的内存使用,但是我还没有找到C的代码来正确地清除内存。< /P>
/*

  Compile with:
  gcc -O2 -Wall mycurl.c -o mycurl -L/usr/include/curl/lib -lcurl

  Courtesy of:
  https://curl.haxx.se/libcurl/c/getinmemory.html

*/

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

struct MemoryStruct {
  char *memory;
  size_t size;
};

static size_t
WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp)
{
  size_t realsize = size * nmemb;
  struct MemoryStruct *mem = (struct MemoryStruct *)userp;

  char *ptr = realloc(mem->memory, mem->size + realsize + 1);
  if(ptr == NULL) {
    /* out of memory! */ 
    printf("not enough memory (realloc returned NULL)\n");
    return 0;
  }

  mem->memory = ptr;
  memcpy(&(mem->memory[mem->size]), contents, realsize);
  mem->size += realsize;
  mem->memory[mem->size] = 0;
  return realsize;
}

int main(void)
{
  CURL *curl;
  CURLcode res;

  struct MemoryStruct chunk;

  chunk.memory = malloc(1);
  chunk.size = 0; 

  curl_global_init(CURL_GLOBAL_ALL);

  curl = curl_easy_init();

  curl_easy_setopt(curl, CURLOPT_URL, "https://www.google.com/");
  curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
  curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);
  curl_easy_setopt(curl, CURLOPT_USERAGENT, "libcurl-agent/1.0");

  res = curl_easy_perform(curl);

/* check for errors */ 
  if(res != CURLE_OK) {
    fprintf(stderr, "curl_easy_perform() failed: %s\n",
            curl_easy_strerror(res));
    return 1;
  }

  printf("%lu bytes retrieved\n", (unsigned long)chunk.size);

  curl_easy_cleanup(curl);
  free(chunk.memory);
  curl_global_cleanup();

  /* Everything is all cleaned up, so the memory usage should be back to      normal at this point. */

  printf("Waiting 3 seconds... Watch to see if the memory levels change between now and when the program says 'Done!' If you see a change in memory, there is likely a leak.)\n");


  /* When the program shuts down, the memory is released, but it should release after we cleanup and before the program terminates. Lets give ourselves a few seconds to spot if this is the case. Make sure to have 'top' or 'htop' open and  */

  sleep(3); // top and htop default at 3 second intervals, so we need more than that to spot a change


  printf("\nDone!\nDid the memory change?\n");

  return 0;
}
为了抓住问题的核心,我将使用只关注手头问题的代码,这些代码有着完全相同的问题。该图摘自本网站:

/*

  Compile with:
  gcc -O2 -Wall mycurl.c -o mycurl -L/usr/include/curl/lib -lcurl

  Courtesy of:
  https://curl.haxx.se/libcurl/c/getinmemory.html

*/

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

struct MemoryStruct {
  char *memory;
  size_t size;
};

static size_t
WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp)
{
  size_t realsize = size * nmemb;
  struct MemoryStruct *mem = (struct MemoryStruct *)userp;

  char *ptr = realloc(mem->memory, mem->size + realsize + 1);
  if(ptr == NULL) {
    /* out of memory! */ 
    printf("not enough memory (realloc returned NULL)\n");
    return 0;
  }

  mem->memory = ptr;
  memcpy(&(mem->memory[mem->size]), contents, realsize);
  mem->size += realsize;
  mem->memory[mem->size] = 0;
  return realsize;
}

int main(void)
{
  CURL *curl;
  CURLcode res;

  struct MemoryStruct chunk;

  chunk.memory = malloc(1);
  chunk.size = 0; 

  curl_global_init(CURL_GLOBAL_ALL);

  curl = curl_easy_init();

  curl_easy_setopt(curl, CURLOPT_URL, "https://www.google.com/");
  curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
  curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);
  curl_easy_setopt(curl, CURLOPT_USERAGENT, "libcurl-agent/1.0");

  res = curl_easy_perform(curl);

/* check for errors */ 
  if(res != CURLE_OK) {
    fprintf(stderr, "curl_easy_perform() failed: %s\n",
            curl_easy_strerror(res));
    return 1;
  }

  printf("%lu bytes retrieved\n", (unsigned long)chunk.size);

  curl_easy_cleanup(curl);
  free(chunk.memory);
  curl_global_cleanup();

  /* Everything is all cleaned up, so the memory usage should be back to      normal at this point. */

  printf("Waiting 3 seconds... Watch to see if the memory levels change between now and when the program says 'Done!' If you see a change in memory, there is likely a leak.)\n");


  /* When the program shuts down, the memory is released, but it should release after we cleanup and before the program terminates. Lets give ourselves a few seconds to spot if this is the case. Make sure to have 'top' or 'htop' open and  */

  sleep(3); // top and htop default at 3 second intervals, so we need more than that to spot a change


  printf("\nDone!\nDid the memory change?\n");

  return 0;
}
顺便说一句,我也尝试过使用这段代码,但运气不好。我想,如果我只是转储数据,我至少可以ping一个站点并检查我的网络是否正常,但它仍然拥有15Mb的内存:

/*

  Compile with:
  gcc -O2 -Wall mycurl.c -o mycurl -L/usr/include/curl/lib -lcurl

  Courtesy of:
  https://curl.haxx.se/libcurl/c/getinmemory.html

*/

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

struct MemoryStruct {
  char *memory;
  size_t size;
};

static size_t
WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp)
{
  size_t realsize = size * nmemb;
  struct MemoryStruct *mem = (struct MemoryStruct *)userp;

  char *ptr = realloc(mem->memory, mem->size + realsize + 1);
  if(ptr == NULL) {
    /* out of memory! */ 
    printf("not enough memory (realloc returned NULL)\n");
    return 0;
  }

  mem->memory = ptr;
  memcpy(&(mem->memory[mem->size]), contents, realsize);
  mem->size += realsize;
  mem->memory[mem->size] = 0;
  return realsize;
}

int main(void)
{
  CURL *curl;
  CURLcode res;

  struct MemoryStruct chunk;

  chunk.memory = malloc(1);
  chunk.size = 0; 

  curl_global_init(CURL_GLOBAL_ALL);

  curl = curl_easy_init();

  curl_easy_setopt(curl, CURLOPT_URL, "https://www.google.com/");
  curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
  curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);
  curl_easy_setopt(curl, CURLOPT_USERAGENT, "libcurl-agent/1.0");

  res = curl_easy_perform(curl);

/* check for errors */ 
  if(res != CURLE_OK) {
    fprintf(stderr, "curl_easy_perform() failed: %s\n",
            curl_easy_strerror(res));
    return 1;
  }

  printf("%lu bytes retrieved\n", (unsigned long)chunk.size);

  curl_easy_cleanup(curl);
  free(chunk.memory);
  curl_global_cleanup();

  /* Everything is all cleaned up, so the memory usage should be back to      normal at this point. */

  printf("Waiting 3 seconds... Watch to see if the memory levels change between now and when the program says 'Done!' If you see a change in memory, there is likely a leak.)\n");


  /* When the program shuts down, the memory is released, but it should release after we cleanup and before the program terminates. Lets give ourselves a few seconds to spot if this is the case. Make sure to have 'top' or 'htop' open and  */

  sleep(3); // top and htop default at 3 second intervals, so we need more than that to spot a change


  printf("\nDone!\nDid the memory change?\n");

  return 0;
}
我听说过curl泄漏,但我无法真正验证这是否是实际泄漏,或者我只是没有正确释放内存

/*

  Compile with:
  gcc -O2 -Wall mycurl.c -o mycurl -L/usr/include/curl/lib -lcurl

  Courtesy of:
  https://curl.haxx.se/libcurl/c/getinmemory.html

*/

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

struct MemoryStruct {
  char *memory;
  size_t size;
};

static size_t
WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp)
{
  size_t realsize = size * nmemb;
  struct MemoryStruct *mem = (struct MemoryStruct *)userp;

  char *ptr = realloc(mem->memory, mem->size + realsize + 1);
  if(ptr == NULL) {
    /* out of memory! */ 
    printf("not enough memory (realloc returned NULL)\n");
    return 0;
  }

  mem->memory = ptr;
  memcpy(&(mem->memory[mem->size]), contents, realsize);
  mem->size += realsize;
  mem->memory[mem->size] = 0;
  return realsize;
}

int main(void)
{
  CURL *curl;
  CURLcode res;

  struct MemoryStruct chunk;

  chunk.memory = malloc(1);
  chunk.size = 0; 

  curl_global_init(CURL_GLOBAL_ALL);

  curl = curl_easy_init();

  curl_easy_setopt(curl, CURLOPT_URL, "https://www.google.com/");
  curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
  curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);
  curl_easy_setopt(curl, CURLOPT_USERAGENT, "libcurl-agent/1.0");

  res = curl_easy_perform(curl);

/* check for errors */ 
  if(res != CURLE_OK) {
    fprintf(stderr, "curl_easy_perform() failed: %s\n",
            curl_easy_strerror(res));
    return 1;
  }

  printf("%lu bytes retrieved\n", (unsigned long)chunk.size);

  curl_easy_cleanup(curl);
  free(chunk.memory);
  curl_global_cleanup();

  /* Everything is all cleaned up, so the memory usage should be back to      normal at this point. */

  printf("Waiting 3 seconds... Watch to see if the memory levels change between now and when the program says 'Done!' If you see a change in memory, there is likely a leak.)\n");


  /* When the program shuts down, the memory is released, but it should release after we cleanup and before the program terminates. Lets give ourselves a few seconds to spot if this is the case. Make sure to have 'top' or 'htop' open and  */

  sleep(3); // top and htop default at 3 second intervals, so we need more than that to spot a change


  printf("\nDone!\nDid the memory change?\n");

  return 0;
}
mycurl.c:

/*

  Compile with:
  gcc -O2 -Wall mycurl.c -o mycurl -L/usr/include/curl/lib -lcurl

  Courtesy of:
  https://curl.haxx.se/libcurl/c/getinmemory.html

*/

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

struct MemoryStruct {
  char *memory;
  size_t size;
};

static size_t
WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp)
{
  size_t realsize = size * nmemb;
  struct MemoryStruct *mem = (struct MemoryStruct *)userp;

  char *ptr = realloc(mem->memory, mem->size + realsize + 1);
  if(ptr == NULL) {
    /* out of memory! */ 
    printf("not enough memory (realloc returned NULL)\n");
    return 0;
  }

  mem->memory = ptr;
  memcpy(&(mem->memory[mem->size]), contents, realsize);
  mem->size += realsize;
  mem->memory[mem->size] = 0;
  return realsize;
}

int main(void)
{
  CURL *curl;
  CURLcode res;

  struct MemoryStruct chunk;

  chunk.memory = malloc(1);
  chunk.size = 0; 

  curl_global_init(CURL_GLOBAL_ALL);

  curl = curl_easy_init();

  curl_easy_setopt(curl, CURLOPT_URL, "https://www.google.com/");
  curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
  curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);
  curl_easy_setopt(curl, CURLOPT_USERAGENT, "libcurl-agent/1.0");

  res = curl_easy_perform(curl);

/* check for errors */ 
  if(res != CURLE_OK) {
    fprintf(stderr, "curl_easy_perform() failed: %s\n",
            curl_easy_strerror(res));
    return 1;
  }

  printf("%lu bytes retrieved\n", (unsigned long)chunk.size);

  curl_easy_cleanup(curl);
  free(chunk.memory);
  curl_global_cleanup();

  /* Everything is all cleaned up, so the memory usage should be back to      normal at this point. */

  printf("Waiting 3 seconds... Watch to see if the memory levels change between now and when the program says 'Done!' If you see a change in memory, there is likely a leak.)\n");


  /* When the program shuts down, the memory is released, but it should release after we cleanup and before the program terminates. Lets give ourselves a few seconds to spot if this is the case. Make sure to have 'top' or 'htop' open and  */

  sleep(3); // top and htop default at 3 second intervals, so we need more than that to spot a change


  printf("\nDone!\nDid the memory change?\n");

  return 0;
}
Debian上的上述代码将卸载“libcurl4 gnutls dev”,并在其位置安装libcurl4 openssl dev。这就解决了这个问题

/*

  Compile with:
  gcc -O2 -Wall mycurl.c -o mycurl -L/usr/include/curl/lib -lcurl

  Courtesy of:
  https://curl.haxx.se/libcurl/c/getinmemory.html

*/

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

struct MemoryStruct {
  char *memory;
  size_t size;
};

static size_t
WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp)
{
  size_t realsize = size * nmemb;
  struct MemoryStruct *mem = (struct MemoryStruct *)userp;

  char *ptr = realloc(mem->memory, mem->size + realsize + 1);
  if(ptr == NULL) {
    /* out of memory! */ 
    printf("not enough memory (realloc returned NULL)\n");
    return 0;
  }

  mem->memory = ptr;
  memcpy(&(mem->memory[mem->size]), contents, realsize);
  mem->size += realsize;
  mem->memory[mem->size] = 0;
  return realsize;
}

int main(void)
{
  CURL *curl;
  CURLcode res;

  struct MemoryStruct chunk;

  chunk.memory = malloc(1);
  chunk.size = 0; 

  curl_global_init(CURL_GLOBAL_ALL);

  curl = curl_easy_init();

  curl_easy_setopt(curl, CURLOPT_URL, "https://www.google.com/");
  curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
  curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);
  curl_easy_setopt(curl, CURLOPT_USERAGENT, "libcurl-agent/1.0");

  res = curl_easy_perform(curl);

/* check for errors */ 
  if(res != CURLE_OK) {
    fprintf(stderr, "curl_easy_perform() failed: %s\n",
            curl_easy_strerror(res));
    return 1;
  }

  printf("%lu bytes retrieved\n", (unsigned long)chunk.size);

  curl_easy_cleanup(curl);
  free(chunk.memory);
  curl_global_cleanup();

  /* Everything is all cleaned up, so the memory usage should be back to      normal at this point. */

  printf("Waiting 3 seconds... Watch to see if the memory levels change between now and when the program says 'Done!' If you see a change in memory, there is likely a leak.)\n");


  /* When the program shuts down, the memory is released, but it should release after we cleanup and before the program terminates. Lets give ourselves a few seconds to spot if this is the case. Make sure to have 'top' or 'htop' open and  */

  sleep(3); // top and htop default at 3 second intervals, so we need more than that to spot a change


  printf("\nDone!\nDid the memory change?\n");

  return 0;
}
下面是我切换到libcurl4-openssl-dev前后的站点列表。所有站点上的内存消耗从15Mb变为1Mb或更少

/*

  Compile with:
  gcc -O2 -Wall mycurl.c -o mycurl -L/usr/include/curl/lib -lcurl

  Courtesy of:
  https://curl.haxx.se/libcurl/c/getinmemory.html

*/

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

struct MemoryStruct {
  char *memory;
  size_t size;
};

static size_t
WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp)
{
  size_t realsize = size * nmemb;
  struct MemoryStruct *mem = (struct MemoryStruct *)userp;

  char *ptr = realloc(mem->memory, mem->size + realsize + 1);
  if(ptr == NULL) {
    /* out of memory! */ 
    printf("not enough memory (realloc returned NULL)\n");
    return 0;
  }

  mem->memory = ptr;
  memcpy(&(mem->memory[mem->size]), contents, realsize);
  mem->size += realsize;
  mem->memory[mem->size] = 0;
  return realsize;
}

int main(void)
{
  CURL *curl;
  CURLcode res;

  struct MemoryStruct chunk;

  chunk.memory = malloc(1);
  chunk.size = 0; 

  curl_global_init(CURL_GLOBAL_ALL);

  curl = curl_easy_init();

  curl_easy_setopt(curl, CURLOPT_URL, "https://www.google.com/");
  curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
  curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);
  curl_easy_setopt(curl, CURLOPT_USERAGENT, "libcurl-agent/1.0");

  res = curl_easy_perform(curl);

/* check for errors */ 
  if(res != CURLE_OK) {
    fprintf(stderr, "curl_easy_perform() failed: %s\n",
            curl_easy_strerror(res));
    return 1;
  }

  printf("%lu bytes retrieved\n", (unsigned long)chunk.size);

  curl_easy_cleanup(curl);
  free(chunk.memory);
  curl_global_cleanup();

  /* Everything is all cleaned up, so the memory usage should be back to      normal at this point. */

  printf("Waiting 3 seconds... Watch to see if the memory levels change between now and when the program says 'Done!' If you see a change in memory, there is likely a leak.)\n");


  /* When the program shuts down, the memory is released, but it should release after we cleanup and before the program terminates. Lets give ourselves a few seconds to spot if this is the case. Make sure to have 'top' or 'htop' open and  */

  sleep(3); // top and htop default at 3 second intervals, so we need more than that to spot a change


  printf("\nDone!\nDid the memory change?\n");

  return 0;
}
为了让其他用户能够轻松测试他们的情况是否如此,我保留了所有测试代码,这些代码可以快速剪切粘贴并运行:

/*

  Compile with:
  gcc -O2 -Wall mycurl.c -o mycurl -L/usr/include/curl/lib -lcurl

  Courtesy of:
  https://curl.haxx.se/libcurl/c/getinmemory.html

*/

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

struct MemoryStruct {
  char *memory;
  size_t size;
};

static size_t
WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp)
{
  size_t realsize = size * nmemb;
  struct MemoryStruct *mem = (struct MemoryStruct *)userp;

  char *ptr = realloc(mem->memory, mem->size + realsize + 1);
  if(ptr == NULL) {
    /* out of memory! */ 
    printf("not enough memory (realloc returned NULL)\n");
    return 0;
  }

  mem->memory = ptr;
  memcpy(&(mem->memory[mem->size]), contents, realsize);
  mem->size += realsize;
  mem->memory[mem->size] = 0;
  return realsize;
}

int main(void)
{
  CURL *curl;
  CURLcode res;

  struct MemoryStruct chunk;

  chunk.memory = malloc(1);
  chunk.size = 0; 

  curl_global_init(CURL_GLOBAL_ALL);

  curl = curl_easy_init();

  curl_easy_setopt(curl, CURLOPT_URL, "https://www.google.com/");
  curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
  curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);
  curl_easy_setopt(curl, CURLOPT_USERAGENT, "libcurl-agent/1.0");

  res = curl_easy_perform(curl);

/* check for errors */ 
  if(res != CURLE_OK) {
    fprintf(stderr, "curl_easy_perform() failed: %s\n",
            curl_easy_strerror(res));
    return 1;
  }

  printf("%lu bytes retrieved\n", (unsigned long)chunk.size);

  curl_easy_cleanup(curl);
  free(chunk.memory);
  curl_global_cleanup();

  /* Everything is all cleaned up, so the memory usage should be back to      normal at this point. */

  printf("Waiting 3 seconds... Watch to see if the memory levels change between now and when the program says 'Done!' If you see a change in memory, there is likely a leak.)\n");


  /* When the program shuts down, the memory is released, but it should release after we cleanup and before the program terminates. Lets give ourselves a few seconds to spot if this is the case. Make sure to have 'top' or 'htop' open and  */

  sleep(3); // top and htop default at 3 second intervals, so we need more than that to spot a change


  printf("\nDone!\nDid the memory change?\n");

  return 0;
}
//curl_easy_setopt(curl, CURLOPT_URL, "https://kernel.org"); // before +15Mb, after +1Mb
  //curl_easy_setopt(curl, CURLOPT_URL, "https://stackoverflow.com"); // before +15Mb, after +1Mb
  //curl_easy_setopt(curl, CURLOPT_URL, "https://blog.apastyle.org/"); // before +15Mb, after +1Mb
  //curl_easy_setopt(curl, CURLOPT_URL, "http://forums.debian.net"); // before +0Mb, after +1Mb
  //curl_easy_setopt(curl, CURLOPT_URL, "http://support.blog.com/create-a-blog/"); // before +0Mb, after +1Mb
  //curl_easy_setopt(curl, CURLOPT_URL, "http://blog.alz.org/"); // before +0Mb, after +0Mb
记忆使用的昼夜差异。很高兴解决了这个问题。再次感谢hlscalon和FredK的超级英雄速度回复和提示

/*

  Compile with:
  gcc -O2 -Wall mycurl.c -o mycurl -L/usr/include/curl/lib -lcurl

  Courtesy of:
  https://curl.haxx.se/libcurl/c/getinmemory.html

*/

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

struct MemoryStruct {
  char *memory;
  size_t size;
};

static size_t
WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp)
{
  size_t realsize = size * nmemb;
  struct MemoryStruct *mem = (struct MemoryStruct *)userp;

  char *ptr = realloc(mem->memory, mem->size + realsize + 1);
  if(ptr == NULL) {
    /* out of memory! */ 
    printf("not enough memory (realloc returned NULL)\n");
    return 0;
  }

  mem->memory = ptr;
  memcpy(&(mem->memory[mem->size]), contents, realsize);
  mem->size += realsize;
  mem->memory[mem->size] = 0;
  return realsize;
}

int main(void)
{
  CURL *curl;
  CURLcode res;

  struct MemoryStruct chunk;

  chunk.memory = malloc(1);
  chunk.size = 0; 

  curl_global_init(CURL_GLOBAL_ALL);

  curl = curl_easy_init();

  curl_easy_setopt(curl, CURLOPT_URL, "https://www.google.com/");
  curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
  curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);
  curl_easy_setopt(curl, CURLOPT_USERAGENT, "libcurl-agent/1.0");

  res = curl_easy_perform(curl);

/* check for errors */ 
  if(res != CURLE_OK) {
    fprintf(stderr, "curl_easy_perform() failed: %s\n",
            curl_easy_strerror(res));
    return 1;
  }

  printf("%lu bytes retrieved\n", (unsigned long)chunk.size);

  curl_easy_cleanup(curl);
  free(chunk.memory);
  curl_global_cleanup();

  /* Everything is all cleaned up, so the memory usage should be back to      normal at this point. */

  printf("Waiting 3 seconds... Watch to see if the memory levels change between now and when the program says 'Done!' If you see a change in memory, there is likely a leak.)\n");


  /* When the program shuts down, the memory is released, but it should release after we cleanup and before the program terminates. Lets give ourselves a few seconds to spot if this is the case. Make sure to have 'top' or 'htop' open and  */

  sleep(3); // top and htop default at 3 second intervals, so we need more than that to spot a change


  printf("\nDone!\nDid the memory change?\n");

  return 0;
}

考虑到这篇文章仍然可以回复关于libcurl4gnutls开发正在修复的问题。遗憾的是,这似乎是一个已经存在了几年的bug,所以我没有屏息以待。

当你调用
free()
时,无法保证你的操作系统会减少你的足迹。它只保证内存空间可供程序重用;这取决于操作系统,取决于何时(或是否)您的大小将实际减小..根据这一点,curl可能没有问题,可能是gnutls。如果你使用HTTP或OpenSSL,你有相同的内存分配量吗?FRIDK:奇怪的是,C++可以很好地减少它的大小。好消息,但要知道。谢谢我做了一个小测试(原始帖子中的结果),发现结果确实反映了你所说的:访问https站点与访问http站点时,内存消耗肯定有所不同。后者似乎没有任何问题。我读了一些那篇文章。然后我安装了“libcurl4openssl-dev”(Debian),它自动卸载了“libcurl4gnutls-dev”,http和https站点的问题完全消失了。解决了。。。现在。
/*

  Compile with:
  gcc -O2 -Wall mycurl.c -o mycurl -L/usr/include/curl/lib -lcurl

  Courtesy of:
  https://curl.haxx.se/libcurl/c/getinmemory.html

*/

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

struct MemoryStruct {
  char *memory;
  size_t size;
};

static size_t
WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp)
{
  size_t realsize = size * nmemb;
  struct MemoryStruct *mem = (struct MemoryStruct *)userp;

  char *ptr = realloc(mem->memory, mem->size + realsize + 1);
  if(ptr == NULL) {
    /* out of memory! */ 
    printf("not enough memory (realloc returned NULL)\n");
    return 0;
  }

  mem->memory = ptr;
  memcpy(&(mem->memory[mem->size]), contents, realsize);
  mem->size += realsize;
  mem->memory[mem->size] = 0;
  return realsize;
}

int main(void)
{
  CURL *curl;
  CURLcode res;

  struct MemoryStruct chunk;

  chunk.memory = malloc(1);
  chunk.size = 0; 

  curl_global_init(CURL_GLOBAL_ALL);

  curl = curl_easy_init();

  curl_easy_setopt(curl, CURLOPT_URL, "https://www.google.com/");
  curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
  curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);
  curl_easy_setopt(curl, CURLOPT_USERAGENT, "libcurl-agent/1.0");

  res = curl_easy_perform(curl);

/* check for errors */ 
  if(res != CURLE_OK) {
    fprintf(stderr, "curl_easy_perform() failed: %s\n",
            curl_easy_strerror(res));
    return 1;
  }

  printf("%lu bytes retrieved\n", (unsigned long)chunk.size);

  curl_easy_cleanup(curl);
  free(chunk.memory);
  curl_global_cleanup();

  /* Everything is all cleaned up, so the memory usage should be back to      normal at this point. */

  printf("Waiting 3 seconds... Watch to see if the memory levels change between now and when the program says 'Done!' If you see a change in memory, there is likely a leak.)\n");


  /* When the program shuts down, the memory is released, but it should release after we cleanup and before the program terminates. Lets give ourselves a few seconds to spot if this is the case. Make sure to have 'top' or 'htop' open and  */

  sleep(3); // top and htop default at 3 second intervals, so we need more than that to spot a change


  printf("\nDone!\nDid the memory change?\n");

  return 0;
}