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

时间:2019-03-21 20:18:07

标签: c curl memory free

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

这似乎是在我发出问题时发生的:

curl_easy_perform(curl);

我不知道如何在不关闭程序的情况下释放此内存,并且我需要程序保持打开状态。我不想创建一个单独的程序并调用它,因为将来我想在该程序中使用curl来实现其他功能(例如ping网络以检查连接),所以我也可能只要在它在那里就可以使用。

我已经在C ++中完美地完成了这一工作,没有占用额外的内存,但是我还没有找到正确清除内存的C代码。

为了深入了解情况,我将使用仅专注于当前问题且具有完全相同问题的代码。它取自本网站: https://curl.haxx.se/libcurl/c/getinmemory.html

顺便说一句,我也尝试过使用此代码,但没有运气。我以为也许我只是转储了数据,但我至少可以对一个站点执行ping操作,并检查我的网络是否正常运行,但是它仍然可以保留15Mb的内存: https://curl.haxx.se/libcurl/c/simple.html

我听说过卷曲泄漏,但是我无法真正验证这是实际泄漏还是只是没有正确释放内存。

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;
}

在程序关闭之前,内存永远不会清除。我希望能够清除该内存并重新使用curl命令。

我确定您想知道我为什么要超过15Mb?

该代码将用于Raspberry Pi Zero(仅限于512Mb ram(无法升级)),如果我真的不需要的话,我不想放弃15Mb。目前,我正在Raspberry Pi 3B +上运行此代码。但是,即使在其他体系结构(x86 / 64)上,我也有很长一段时间没有使用curl的问题。

很乐意解决它。谢谢。 :)


****编辑****


向hlscalon提供错误参考链接,并据我所知找出原因。

apt install libcurl4-openssl-dev

以上在Debian上的代码将卸载'libcurl4-gnutls-dev'并在其位置安装libcurl4-openssl-dev。这解决了这种情况。

以下是我切换到libcurl4-openssl-dev之前和之后的站点列表。在所有站点上,内存消耗的变化从15Mb变为1Mb或更小。

为了允许其他用户轻松测试是否适合他们,我保留了所有测试代码,可以快速将其剪切并粘贴并运行:

//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的超级英雄速度回复和提示。

考虑该帖子仍然开放,涉及与已修复的libcurl4-gnutls-dev有关的答复。可悲的是,这似乎是已经存在了两年的错误,所以我没有屏住呼吸。

0 个答案:

没有答案