首页 > 解决方案 > 防止向量使类的所有实例相同

问题描述

这是我需要创建一个向量的结构:

/*
    Structure of a delegate, many expected*/
    struct delegate {
        const char * title;
        const char * name;
        const char * role;
        const char * group;

        delegate(const char * a, const char * b, const char * c, const char * d)
            : title(a),name(b),role(c),group(d)
        {}
    };

问题是,在我将在下面展示的代码中,即使正确收集了不同的数据集并且可以将其构造为类型委托的对象,向量总是以所有实例为同一个对象而结束,但是在调试时它是很明显,用于构造向量中对象的数据是不同的,那么为什么会这样呢?编码:

    std::vector <delegate> delegates;
    ss << "SELECT Title,FirstName,MiddleName,LastName,Role,PartyId FROM Attendee WHERE eventId = ?", use(eventId), now;
    Poco::Data::RecordSet RecordSet(ss);
    ss.reset(*db_session);
    for (auto& record : RecordSet) {
        std::string result;
        delTitle = record.get(0).toString();
        delName = record.get(1).toString();
        delName.append(" ");
        delName.append(record.get(2).toString());
        delName.append(" ");
        delName.append(record.get(3).toString());
        delRole = record.get(4).toString();
        partyId = record.get(5).toString();
        ss << "SELECT '1' FROM Party WHERE Id = ?", into(result), use(partyId);
        ss.reset(*db_session);
        if (result != "")
        {
            ss << "SELECT Name FROM Party WHERE Id = ?", into(party), use(partyId), now;
            ss.reset(*db_session);
        }
        else
            party = "N/A";
        const char * delname = delName.c_str();
        const char * delrole = delRole.c_str();
        const char * deltitle = delTitle.c_str();
        const char * delgroup = party.c_str();
        delegates.emplace_back(deltitle, delname, delrole,delgroup);
    }

向量总是以对象的所有实例与放置在向量上的最后一个对象相同而结束。第一个值很好,但第二个添加会重写第一个值,因此它们都成为同一个对象,依此类推。

感谢任何帮助。

标签: c++vector

解决方案


问题中的代码调用未定义的行为。

    const char * delname = delName.c_str();
    const char * delrole = delRole.c_str();
    const char * deltitle = delTitle.c_str();
    const char * delgroup = party.c_str();
    delegates.emplace_back(deltitle, delname, delrole,delgroup);

看看cppreference对此有何评论:

从 c_str() 获得的指针可能会通过以下方式失效:

  • 将对字符串的非常量引用传递给任何标准库函数,或

  • 在字符串上调用非常量成员函数,不包括 operator[]、at()、front()、back()、begin()、rbegin()、end() 和 rend()。

这意味着赋值运算符:

    delTitle = record.get(0).toString();

无效delTitle.c_str()。这意味着您delegates包含一堆无效指针,并且取消引用它们会调用未定义的行为。

您不会发生崩溃,因为很可能所有字符串变体都重用了相同的内部缓冲区。这纯粹是运气,使用不同的字符串可能会有所不同。例如,如果字符串在每次迭代中变得越来越大,那么缓冲区将被重新分配,并且您的指针将指向一些垃圾。

正确的做法是存储std::string而不是char *.


推荐阅读