2016-01-10 2 views
2

Я пытаюсь написать функцию, которая возвращает HTML-код указанного URL вот мой код до сих пор:Я хочу, чтобы написать функцию, которая получает веб-страницу

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 

вот мой writememorycallback:

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

тот же код, когда он встроен в тело основной функции, работает просто отлично.

+0

Пожалуйста, открепите код, я просто сделал это для другого сообщения. Например, установите 'astyle' и просто' astyle -A1 mysourcefile.c'. И здесь 'struct BufferStruct * mem = (struct BufferStruct *) data;' it может быть 'struct BufferStruct * mem = data;'! Кроме того, 'mem-> buffer = realloc (mem-> buffer, mem-> size + realsize + 1);' what if 'mem-> buffer' является' NULL' после 'realloc()'? Ваша программа будет утечка памяти! –

+0

Вы уверены, что передать неинициализированный указатель на 'curl_easy_setopt' - хорошая идея? Я уверен, что вы вызываете неопределенное поведение. – szczurcio

+0

@szczurcio Нет проблем, но он должен быть инициализирован до 'curl_easy_perform()'. –

ответ

2

Если только первая строка успех распечатывается потом что-то пошло не так, вероятно, с первого вызова функции завитка.

Первый шаг вы должны сделать, это проверить каждое возвращаемое значение локон функций:

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

Реальная причина этого первого вызова функции ротора не удалось, что CURL *myHandle не был инициализирован:

Так инициализировать его:

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

И удалить его после того, как вы сделали:

curl_easy_cleanup(myHandle); 

Другая проблема, как уже указывалось, заключается в том, что struct BufferStruct buffer не инициализирован, поэтому realloc в WriteMemoryCallback не работает при вызове с неинициализированным указателем.

+1

yup, это было, спасибо :) –

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 
+0

да, я получаю тот же результат, я изменил свой код, чтобы проверить, является ли mem-> buffer NULL после realloc. –

Смежные вопросы