这是我需要创建以下向量的结构:
/*
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);
}
向量总是以对象的所有实例与放置在向量上的最后一个实例相同而结束。第一个值很好,但是第二个加法重写了第一个,因此它们都成为同一对象,依此类推上。
感谢您的帮助。
答案 0 :(得分:0)
问题中的代码调用未定义的行为。
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()。 / p>
这意味着赋值运算符:
delTitle = record.get(0).toString();
使delTitle.c_str()
无效。这意味着您的delegates
包含一堆无效的指针,而取消引用它们会调用未定义的行为。
您不会崩溃,因为很有可能,相同的内部缓冲区可用于所有字符串变体。这真是运气,使用不同的字符串可能会有所不同。例如,如果字符串在每次迭代中变得越来越大,则缓冲区将被重新分配,并且指针将指向某些垃圾。
正确的做法是存储std::string
而不是char *
。