我想编写一个检索网页的函数

时间:2016-01-10 11:51:07

标签: c linux libcurl

我试图编写一个返回指定URL的html代码的函数 到目前为止,这是我的代码:

char * getHtml()
{
    struct BufferStruct buffer;
    CURLcode result;
    CURL *myHandle;

    printf("success\n");
    // Passing the function pointer to LC
    curl_easy_setopt(myHandle, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
    printf("success\n");
     // Passing our BufferStruct to LC
    curl_easy_setopt(myHandle, CURLOPT_WRITEDATA, (void *)&buffer);
    curl_easy_setopt(myHandle, CURLOPT_URL, "http://www.example.com");

    result = curl_easy_perform( myHandle );

    curl_easy_cleanup( myHandle );
    return buffer.buffer;
}

仅打印第一个成功字符串: 成功

./compile: line 3: 27548 Segmentation fault      ./a.out

这是我的写作记录:

static size_t WriteMemoryCallback (void *ptr, size_t size, size_t nmemb, void *data)
{
    size_t realsize = size * nmemb;        
    struct BufferStruct *mem = (struct BufferStruct *) data;

    mem->buffer = realloc(mem->buffer, mem->size + realsize + 1);   
    if (mem->buffer == NULL)
        return 0;

    if (mem->buffer)
    {
        memcpy(&(mem->buffer[ mem->size ]), ptr, realsize);
        mem->size += realsize;
        mem->buffer[ mem->size ] = 0;
    }
    return realsize;
}
嵌入到main函数体中的相同代码工作正常。

2 个答案:

答案 0 :(得分:2)

如果只打印出第一个字符串 success ,那么第一次调用curl函数时可能会出错。

您应该做的第一步是检查curl函数的每个返回值:

CURLcode ok = curl_easy_setopt(myHandle, CURLOPT_WRITEFUNCTION, WriteMemoryCallback);
if( ok != CURLE_OK )
{
    printf( "Error here %d\n" , __LINE__ );
}

第一次调用curl函数失败的真正原因是CURL *myHandle没有初始化:

初始化它:

CURL *myHandle= curl_easy_init();
if(!myHandle) { /*handle error ...*/ }

完成后删除它:

curl_easy_cleanup(myHandle);

已经指出的另一个问题是struct BufferStruct buffer没有被初始化,因此当使用未初始化的指针调用时,WriteMemoryCallback中的realloc失败。

答案 1 :(得分:1)

您永远不会初始化buffer,您应该将buffer.buffer设置为NULL,以使realloc()按预期工作,并且buffer.size必须初始化为或者你的程序会调用未定义的行为。

您应该在getHtml()

中执行此操作
buffer.buffer = NULL;
buffer.size = 0;
curl_easy_perform()之前

另外,要以安全的方式使用realloc(),请执行此操作

void *aux;
aux = realloc(mem->buffer, mem->size + realsize + 1);
if (aux == NULL)
    return 0; // Maybe `free(mem->buffer); mem->buffer = NULL; mem->size = 0;'
mem->buffer = aux;
// Continue, memcpy() and update mem->size