芥末三文鱼 2014-08-02 06:13 采纳率: 0%
浏览 1646

封装的libcurl类在使用vector时出错

环境:
系统:Windows 8专业版(32位)
IDE:VS 2013
curl库版本:libcurl-7.19.3-win32-ssl-msvc
运行时提示

0x61DE35F7 (curllib.dll) (curltest.exe 中)处有未经处理的异常: 0xC0000005: 读取位置 0xFEEEFF02 时发生访问冲突。

#include "stdafx.h"
#include "curl/curl.h"
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
#include <io.h>


#pragma comment(lib, "curl/libcurl_imp.lib")

#define PROGNAME "curltest"
#define RETRY_TIME 5
#define URL_SIZE 100

using namespace std;

size_t print_callback(char* buffer, size_t size, size_t nitems, void *outstream)
{
    return nitems;
}

size_t write_callback(char* buffer, size_t size, size_t nitems, string &text)
{
size_t sizes = size * nitems;
string temp(buffer, sizes);
text += temp;
return sizes;
}

int progress_callback(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow)
{
printf("%.1f%%\t", 100 * (dlnow / dltotal));
cout << "\r";
cout.flush();
return 0;
}

class Novel
{
private:
CURL *eh;
CURLcode res;
int http_code;
int retry_time;
public:
int id;
double filesize;
bool is_exist;
char *url = new char[URL_SIZE];
string *text = new string;
Novel(int id)
{
    this->id = id;
    retry_time = RETRY_TIME;
    sprintf_s(url, URL_SIZE, "dl.wenku8.cn/down.php?type=txt&id=%d", id);
    eh = curl_easy_init();
    curl_easy_setopt(eh, CURLOPT_URL, url);
    curl_easy_setopt(eh, CURLOPT_WRITEFUNCTION, print_callback);
    curl_easy_setopt(eh, CURLOPT_NOPROGRESS, 1);
    curl_easy_setopt(eh, CURLOPT_PROGRESSFUNCTION, progress_callback);
    curl_easy_setopt(eh, CURLOPT_FOLLOWLOCATION, 1);
    curl_easy_setopt(eh, CURLOPT_HEADER, 1);
    curl_easy_setopt(eh, CURLOPT_NOBODY, 1);
    res = curl_easy_perform(eh);
    curl_easy_getinfo(eh, CURLINFO_HTTP_CODE, &http_code);
    if (http_code == 404)
    {
        is_exist = false;
        filesize = -1;
        return;
    }
    else
        is_exist = true;
    curl_easy_getinfo(eh, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &filesize);
}
int start()
{
    if (is_exist == false)
    {
        cerr << "文件不存在" << endl;
        return 1;
    }
    else
    {
        curl_easy_setopt(eh, CURLOPT_WRITEFUNCTION, write_callback);
        curl_easy_setopt(eh, CURLOPT_NOBODY, 0);
        curl_easy_setopt(eh, CURLOPT_HEADER, 0);
        curl_easy_setopt(eh, CURLOPT_NOPROGRESS, 0);
        curl_easy_setopt(eh, CURLOPT_WRITEDATA, text);
        cout << "正在下载 " << id << ".txt" << endl;
        res = curl_easy_perform(eh);
        if (res != CURLE_OK)
        {
            cerr << curl_easy_strerror(res) << endl;
            return -1;
        }
        cout << "下载完成" << endl;
    }
    return 0;
}
~Novel()
{
    curl_easy_cleanup(eh);
    delete[] url;
    delete text;
}
};

int main(int argc, char *argv[])
{
/*
    int retry_time = RETRY_TIME;
    int id = 1;
    vector<Novel> vNovel;
    for (id = 1; retry_time!=0; id++)
    {
        vNovel.push_back(id);
        if (vNovel[id - 1].start())
        {
            retry_time--;
        }
        else
        {
            retry_time = RETRY_TIME;
        }
    }
    getchar();
    vNovel.clear();    // 这句出错
*/
// 上面是出错的地方,下面无错
    Novel test(1);
    test.start();
    getchar();
    return 0;
}
  • 写回答

1条回答 默认 最新

  • ChatGPTᴼᴾᴱᴺᴬᴵ 2023-03-16 12:02
    关注

    该回答引用ChatGPT

    问题出在vector中存储了Novel对象,但是Novel类中没有实现拷贝构造函数和赋值运算符重载函数,所以在vector调用元素复制时出错。可以通过实现拷贝构造函数和赋值运算符重载函数解决这个问题。


    在Novel类中添加以下代码:

    Novel(const Novel& other) //拷贝构造函数
    {
        id = other.id;
        filesize = other.filesize;
        is_exist = other.is_exist;
        url = new char[URL_SIZE];
        strcpy_s(url, URL_SIZE, other.url);
        text = new string;
        *text = *other.text;
        eh = curl_easy_init();
        curl_easy_setopt(eh, CURLOPT_URL, url);
        curl_easy_setopt(eh, CURLOPT_WRITEFUNCTION, write_callback);
        curl_easy_setopt(eh, CURLOPT_NOPROGRESS, 0);
        curl_easy_setopt(eh, CURLOPT_PROGRESSFUNCTION, progress_callback);
        curl_easy_setopt(eh, CURLOPT_FOLLOWLOCATION, 1);
        curl_easy_setopt(eh, CURLOPT_HEADER, 0);
        curl_easy_setopt(eh, CURLOPT_NOBODY, 0);
        curl_easy_setopt(eh, CURLOPT_WRITEDATA, text);
    }
    
    Novel& operator=(const Novel& other) //赋值运算符重载函数
    {
        if (this != &other)
        {
            id = other.id;
            filesize = other.filesize;
            is_exist = other.is_exist;
            delete[] url;
            url = new char[URL_SIZE];
            strcpy_s(url, URL_SIZE, other.url);
            delete text;
            text = new string;
            *text = *other.text;
            curl_easy_cleanup(eh);
            eh = curl_easy_init();
            curl_easy_setopt(eh, CURLOPT_URL, url);
            curl_easy_setopt(eh, CURLOPT_WRITEFUNCTION, write_callback);
            curl_easy_setopt(eh, CURLOPT_NOPROGRESS, 0);
            curl_easy_setopt(eh, CURLOPT_PROGRESSFUNCTION, progress_callback);
            curl_easy_setopt(eh, CURLOPT_FOLLOWLOCATION, 1);
            curl_easy_setopt(eh, CURLOPT_HEADER, 0);
            curl_easy_setopt(eh, CURLOPT_NOBODY, 0);
            curl_easy_setopt(eh, CURLOPT_WRITEDATA, text);
        }
        return *this;
    }
    

    这样,在Novel类中就实现了拷贝构造函数和赋值运算符重载函数,可以避免vector调用元素复制时出错。另外,可以通过加入move构造函数和move赋值运算符重载函数进一步优化代码。

    评论

报告相同问题?

悬赏问题

  • ¥15 求差集那个函数有问题,有无佬可以解决
  • ¥15 【提问】基于Invest的水源涵养
  • ¥20 微信网友居然可以通过vx号找到我绑的手机号
  • ¥15 寻一个支付宝扫码远程授权登录的软件助手app
  • ¥15 解riccati方程组
  • ¥15 display:none;样式在嵌套结构中的已设置了display样式的元素上不起作用?
  • ¥15 使用rabbitMQ 消息队列作为url源进行多线程爬取时,总有几个url没有处理的问题。
  • ¥15 Ubuntu在安装序列比对软件STAR时出现报错如何解决
  • ¥50 树莓派安卓APK系统签名
  • ¥65 汇编语言除法溢出问题