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