libCURL动态分配buffer——节约内存
libCURL是一个免费的、开源的强大客户端url传输库。支持的平台、协议甚广。平台上有Windows、Linux、FreeBSD;协议上有FTP、HTTP(S)、Telnet、DICT、File等。它是线程安全的,而且支持ipv6。同时,它还是线程安全的。
本文所讲述的内容,要基于Libcurl的基础、具体的了解。官方具体描述地址在:http://curl.haxx.se/libcurl/c/上面。需要多看例子,才能灵活运用。
通常libCURL的数据下载都是通过回调函数下载到buffer中的。其大小一般固定,所以有时候用了不到1/2,有时候却会overflow。这里给出一个简单易用的方法节约内存,并解决溢出。主要思想是使用STL中的list的char*模板,每次回调时都copy到一个分配了一定内存的指针(要注意的是,libCURL给出的是流数据,所以不一定以0结尾,所以有时候用简单的strcpy时,会出现错误,笔者就在这被坑了很多次),其大小为size*nmemb,然后将给出的数据逐个copy后,push_back到链表即可。
使用这些数据时,有可能需要随机存取,但是list不具备这个特征,所以可以先统计出所有数据的总大小,开一个大buffer,存入即可。当然,在此之后,要把所有的list及char指针释放,否则内存还是双倍。
源代码给出如下:
#include <iostream> #include <list> #include <curl/curl.h> using namespace std; size_t callback_get_head(void *ptr,size_t size,size_t nmemb,void *userp); list<char*> toview; char startht[256]={0}; int main(void){ cout<<"Enter HTTP adress:"; cin>>startht; CURL* dcurl=curl_easy_init(); curl_easy_setopt(dcurl,CURLOPT_URL,startht); curl_easy_setopt(dcurl,CURLOPT_WRITEFUNCTION,callback_get_head); curl_easy_perform(dcurl); for (list<char*>::iterator it=toview.begin();it!=toview.end();++it) cout<<*it; for (list<char*>::iterator it=toview.begin();it!=toview.end();++it) delete[] *it; curl_easy_cleanup(dcurl); return 0; } size_t callback_get_head(void *ptr,size_t size,size_t nmemb,void *userp){ char* temp=new char[size*nmemb+1]; char* ptrtmp=(char*) ptr; for (size_t i=0;i<size*nmemb;++i) temp[i]=ptrtmp[i]; temp[size*nmemb+1]=0; toview.push_back(temp); return size*nmemb; }
——捐赠我(莱特币):Le8Z8dCsEnzyAztUft3EXEDasZw62VSmT3