Ошибка сегментации C ++, вызванная глобальной переменной в отдельном исходном файле

0

Я c++ noob проблема съемки в течение 4 часов. Я получаю свою первую ошибку сегментации. Я думаю, что это происходит из переменных данных. Программа вытаскивает html (используя cURL) с веб-страницы, но seg faults после извлечения некоторого HTML. Я вызываю "curlbar :: getThreads();" от main.cpp. Код работал нормально, когда все было в main.cpp, но когда я положил его в curlbar, я получил ошибку segfault (core dumped):

/*
* 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();
}
};

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

Теги:
string
segmentation-fault

1 ответ

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();

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

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

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню