【问题标题】:write access violation with c++ libcurl使用 C++ libcurl 写访问冲突
【发布时间】:2023-01-13 01:54:21
【问题描述】:

我正在尝试创建从某些 URL 下载数据的 C++ 代码,但它引发了写入访问冲突:

#include <errno.h>
#include <stdlib.h>
#include <string.h>
#ifndef WIN32

#endif
#include <curl/curl.h>
#include <string>

static const char* urls[] = {
  "http://www.example.com",
  "http://www.example1.com",
};

#define MAX_PARALLEL 10 /* number of simultaneous transfers */
#define NUM_URLS sizeof(urls)/sizeof(char *)

static size_t write_cb(void* ptr, size_t size, size_t nmemb, void* buffer)
{
    ((std::string*)buffer)->append((char*)ptr, nmemb);
    return nmemb;
}

static void add_transfer(CURLM* cm, int i, int* left)
{
    CURL* eh = curl_easy_init();
    curl_easy_setopt(eh, CURLOPT_WRITEFUNCTION, write_cb);
    curl_easy_setopt(eh, CURLOPT_URL, urls[i]);
    curl_easy_setopt(eh, CURLOPT_PRIVATE, urls[i]);
    curl_easy_setopt(eh, CURLOPT_WRITEDATA, &write_cb);
    curl_easy_setopt(eh, CURLOPT_VERBOSE, 1L);
    curl_multi_add_handle(cm, eh);
    (*left)++;
}

int main(void)
{
    CURLM* cm;
    unsigned int transfers = 0;
    int msgs_left = -1;
    int left = 0;

    curl_global_init(CURL_GLOBAL_ALL);
    cm = curl_multi_init();

    /* Limit the amount of simultaneous connections curl should allow: */
    curl_multi_setopt(cm, CURLMOPT_MAXCONNECTS, (long)MAX_PARALLEL);

    for (transfers = 0; transfers < MAX_PARALLEL && transfers < NUM_URLS;
        transfers++)
        add_transfer(cm, transfers, &left);

    do {
        int still_alive = 1;
        curl_multi_perform(cm, &still_alive);


        CURLMsg* msg;
        int queued;
        CURLMcode mc = curl_multi_perform(cm, &still_alive);

        if (cm)
            /* wait for activity, timeout or "nothing" */
            mc = curl_multi_poll(cm, NULL, 0, 1000, NULL);

        if (mc)
            break;

        do {
            msg = curl_multi_info_read(cm, &queued);
            if (msg) {
                if (msg->msg == CURLMSG_DONE) {
                    /* a transfer ended */
                    fprintf(stderr, "Transfer completed\n");
                }
            }
        } while (msg);
     
        if (left)
            curl_multi_wait(cm, NULL, 0, 1000, NULL);

    } while (left);

    curl_multi_cleanup(cm);
    curl_global_cleanup();

    return EXIT_SUCCESS;
}

它崩溃了:

_Mypair._Myval2._Mysize = _Old_size + _Count;

完整的错误信息是:

Exception thrown: write access violation.
this was 0x7FF7941D39D0.

如何让这段代码无误地下载每个 Url 数据?

【问题讨论】:

  • 你将CURLOPT_WRITEDATA设置为&amp;write_cb使得((std::string*)buffer)不明智
  • 特别是因为 CURLOPT_PRIVATE 被设置为 const char *。将 const char * 转换为 std::string 总是以泪水告终。
  • 我在代码中没有看到 _Mypair._Myval2._Mysize = _Old_size + _Count; 行。
  • static size_t write_cb(void* ptr, size_t size, size_t nmemb, void* buffer),你是绝对地确定 buffer 指向 std::stringptr 指向 char 数组,而不是 const 并且有 nmemb 元素?特别是 bufferstd::string 似乎很可疑,因为你没有在代码中的任何地方创建任何 std::string,我想 curl 也没有。
  • @SamVarshavchik 传递给CURLOPT_PRIVATE的指针未被使用curl.se/libcurl/c/CURLOPT_PRIVATE.html

标签: c++ libcurl


【解决方案1】:

在您的write_cb() 回调中,您期望buffer 参数指向std::string 对象,但在add_transfer() 中,您将CURLOPT_WRITEDATA 设置为指向write_cb 本身而不是std::string 对象.

【讨论】:

    猜你喜欢
    • 2017-02-22
    • 2021-02-16
    • 2018-12-11
    • 1970-01-01
    • 1970-01-01
    • 2011-04-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多