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;
}
posted @ 2015-03-21 17:47  Darksun2010  阅读(2231)  评论(0编辑  收藏  举报