Hello,
I have the following code in c++. [ Windows Vista / Visual C++ 2008 ]
It works fine if you pass 5 links in the "multiq" at first.
If you pass any more than that it works fine again (populating the map "buffer" correctly) but then it crashes right at the very end of the program so all the code and output is as expected (until the program exits).
I noticed the crash does not happen if you comment out the lines of code that have:
"curl_easy_getinfo(msg->easy_handle, CURLINFO_PRIVATE, &url);"
"curl_easy_setopt(h, CURLOPT_WRITEFUNCTION, getpage);"
"curl_easy_setopt(h, CURLOPT_WRITEDATA, &buffer[urlstring]);"
But this means I cant get the code to do what I want (which is to add => [content] to a map).
Please can anyone, if possible, point out what could be wrong in the code (below)?
Many thanks.
#include <string>
#include <iostream>
#include <map>
#include <sstream>
#include <fstream>
#include <regex>
#include "curl/curl.h"
using namespace std;
typedef map<int, string> MultiQ;
MultiQ multiq;
typedef map<string, string> MultiU;
MultiU multiu;
MultiU buffer;
static int getpage(char *data, size_t size, size_t nmemb, std::string *buffer)
{
int result = 0;
if (buffer != NULL) {
buffer->append(data, size * nmemb);
result = size * nmemb;
}
return result;
}
static void geturl(CURLM *mh, int i, string urlstring)
{
cout << "geturl" << i << "\n";
char *urlbuf = new char[urlstring.length()];
strcpy(urlbuf, urlstring.c_str());
CURL *h = curl_easy_init();
curl_easy_setopt(h, CURLOPT_WRITEFUNCTION, getpage);
curl_easy_setopt(h, CURLOPT_WRITEDATA, &buffer[urlstring]);
curl_easy_setopt(h, CURLOPT_MAXFILESIZE, 100000);
curl_easy_setopt(h, CURLOPT_URL, urlbuf);
curl_easy_setopt(h, CURLOPT_PRIVATE, urlbuf);
//curl_easy_setopt(h, CURLOPT_VERBOSE, 1);
curl_multi_add_handle(mh, h);
}
int main()
{
multiq[0] = "http://chemrefer.com/index.html";
multiq[1] = "http://www.chemrefer.com/chemistry_search.php?page_title=news&submit";
multiq[2] = "http://www.chemrefer.com/chemistry_search.php?page_title=toolbar&submit";
multiq[3] = "http://www.chemrefer.com/chemistry_search.php?page_title=about&submit";
multiq[4] = "http://www.google.co.uk/";
multiq[5] = "http://www.chemrefer.com/chemistry_search.php?page_title=advanced&submit";
multiq[6] = "http://www.chemrefer.com/chemistry_search.php?page_title=contact&submit";
multiq[7] = "http://www.chemrefer.com/chemistry_search.php?page_title=links&submit";
multiq[8] = "http://cppreference.com/wiki/stl/vector/start";
multiu["http://chemrefer.com/index.html"] = "http://chemrefer.com/index.html";
multiu["http://www.chemrefer.com/chemistry_search.php?page_title=news&submit"] = "http://www.chemrefer.com/chemistry_search.php?page_title=news&submit";
multiu["http://www.chemrefer.com/chemistry_search.php?page_title=toolbar&submit"] = "http://www.chemrefer.com/chemistry_search.php?page_title=toolbar&submit";
multiu["http://www.chemrefer.com/chemistry_search.php?page_title=about&submit"] = "http://www.chemrefer.com/chemistry_search.php?page_title=about&submit";
multiu["http://www.google.co.uk/"] = "http://www.google.co.uk/";
multiu["http://www.chemrefer.com/chemistry_search.php?page_title=advanced&submit"] = "http://www.chemrefer.com/chemistry_search.php?page_title=advanced&submit";
multiu["http://www.chemrefer.com/chemistry_search.php?page_title=contact&submit"] = "http://www.chemrefer.com/chemistry_search.php?page_title=contact&submit";
multiu["http://www.chemrefer.com/chemistry_search.php?page_title=links&submit"] = "http://www.chemrefer.com/chemistry_search.php?page_title=links&submit";
multiu["http://cppreference.com/wiki/stl/vector/start"] = "http://cppreference.com/wiki/stl/vector/start";
int max = 5;
int total = 9;//int count = multiq.size();
CURLM *mh;
CURLMsg *msg;
int u = 0;
int running;
int fin = 0;
curl_global_init(CURL_GLOBAL_ALL);
mh = curl_multi_init();
curl_multi_setopt(mh, CURLMOPT_MAXCONNECTS, (long)max);
cout << "After adding maxconnects\n";
for (u = 0; u < max; ++u) geturl(mh, u, multiq[u]); // assuming there are 5+ SUs
cout << "u = " << u << "after adding easy handles\n";
int breaker = 0;
char *url;
std::string urlstr;
for ( ; ; ) {
while (CURLM_CALL_MULTI_PERFORM == curl_multi_perform(mh, &running));
while (msg = curl_multi_info_read(mh, &running)) {
if (msg->msg == CURLMSG_DONE) {
CURL *e = msg->easy_handle;
curl_easy_getinfo(msg->easy_handle, CURLINFO_PRIVATE, &url);
urlstr = url;
cout << multiu[urlstr] << "\n" /*<< buffer[urlstr] << "\n\n\n"*/;
curl_multi_remove_handle(mh, e);
curl_easy_cleanup(e);
//content_urls(urlstr, buffer[urlstr]);
buffer[urlstr].clear();
++breaker;
}
if (u < multiq.size()/*count*/) {
geturl(mh, u, multiq[u]);
++u;
++max;
}
}
if (breaker == max) {
cout << "broke loop\n";
break;
}
}
cout << "out of loop ok\n";
curl_multi_cleanup(mh);
cout << "multicleanup ok\n";
curl_global_cleanup();
cout << "globalcleanup ok\n";
return 0;
}