2014-02-04 3 views
0

Я работаю в режиме C++ noob в течение 4 часов. Я получаю свою первую ошибку сегментации. Я думаю, что это происходит из переменных данных. Программа вытаскивает html (используя cURL) с веб-страницы, но seg faults после извлечения некоторого HTML. Я вызываю «curlbar :: getThreads();» от main.cpp. Код работал хорошо, когда все это было в main.cpp, но когда я положил его в curlbar, я получил Segfault (выкинула) ошибка:C++ Сегментация Неисправность, вызванная глобальной переменной в отдельном исходном файле

/* 
* curlbar.cpp 
* 
* Created on: Feb 2, 2014 
* 
*/ 
//get list of threads 
#include "headers.h" 
class curlbar{ 
public: 
string data; 
size_t writeContents(char* buf, size_t size, size_t nmemb, void* up){ 
     for(unsigned int c = 0; c<size*nmemb; c++){ 
      this->data.push_back(buf[c]); 
     } 
     return size*nmemb; 
} 

static void getThreads(){ 

    CURL* curl; 
    curl_global_init(CURL_GLOBAL_ALL); 
    curl = curl_easy_init(); 

    curl_easy_setopt(curl, CURLOPT_URL, "www.somewebsiteblahblah.com"); 
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &curlbar::writeContents); 
    curl_easy_setopt(curl, CURLOPT_VERBOSE,1L); //tell curl to output its progress 
    curl_easy_perform(curl); 
    curl_easy_cleanup(curl); 
    curl_global_cleanup(); 
} 
}; 

ли «строка данных»; не хватает памяти, выделенной для него? Как мне это исправить?

ответ

2

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

Но вы можете сделать это:

class curlbar 
{ 
private: 
    // callback version used for curl-write-function 
    static size_t writeContents_s(char *buf, size_t size, size_t nmemb, void *up) 
    { 
     curlbar* pThis = static_cast<curlbar*>(up); 
     return pThis->writeContents(buf, size, nmemb); 
    } 

public: 
    std::string data; 

    // member version 
    size_t writeContents(char* buf, size_t size, size_t nmemb) 
    { 
     std::copy(buf, buf+(size*nmemb), std::back_inserter(data)); 
     return size*nmemb; 
    } 

    void getThreads() 
    { 
     CURL* curl; 
     curl_global_init(CURL_GLOBAL_ALL); 
     curl = curl_easy_init(); 

     curl_easy_setopt(curl, CURLOPT_URL, "www.somewebsiteblahblah.com"); 
     curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &curlbar::writeContents_s); 
     curl_easy_setopt(curl, CURLOPT_WRITEDATA, this); // NOTE ADDITION 
     curl_easy_setopt(curl, CURLOPT_VERBOSE,1L); //tell curl to output its progress 
     curl_easy_perform(curl); 
     curl_easy_cleanup(curl); 
     curl_global_cleanup(); 
    } 
}; 

дан curlbar obj; объект, вы вызываете его как

curlbar obj; 
obj.getThreads(); 

Как это работает

Это использует определенный пользователем параметр параметра данных в ручке с легким завиванием для установки кусочно-о-данных который будет отправлен обратно вместе с вашим статическим write-callback. Эти данные предоставляются как параметр void *up для обратного вызова. Поэтому мы передаем указатель this и в статическом обратном вызове используйте static_cast, чтобы дать нам указатель на объект, pThis. Мы используем этот указатель для запуска функции с аналогичным именем, но не нуждаемся в параметре up.

+0

Мне было проще переписать функцию обратного вызова для записи в файл с помощью функции fwrite() ... Я переписал большую часть части. Я попробовал ваше решение, и оно скомпилировалось (но я забыл, почему я не использовал его, это была неделя). Спасибо! (Кроме того, Valgrind отлично подходит для поиска seg-faults) – PSeUdocode

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