【发布时间】: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设置为&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::string,ptr指向char数组,而不是const并且有nmemb元素?特别是buffer是std::string似乎很可疑,因为你没有在代码中的任何地方创建任何std::string,我想curl也没有。 -
@SamVarshavchik 传递给
CURLOPT_PRIVATE的指针未被使用curl.se/libcurl/c/CURLOPT_PRIVATE.html