Не допустить, чтобы вектор сделал все экземпляры класса одинаковыми - PullRequest
0 голосов
/ 19 сентября 2018

Вот структура, из которой мне нужно создать вектор:

/*
    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);
    }

Вектор всегда заканчивается тем, что все экземпляры объекта совпадают с последним наложенным на вектор. Первое значение в порядке, но второе добавление переписывает первое и т. Д.оба они становятся одним и тем же объектом и т. д.

Спасибо за любую помощь, спасибо.

1 Ответ

0 голосов
/ 20 сентября 2018

Код в вопросе вызывает неопределенное поведение.

    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() может быть признан недействительным:

  • Передача неконстантной ссылки на строку в любую стандартную библиотечную функцию или

  • Вызов неконстантные функции-члены в строке, за исключением оператора [], at (), front (), back (), begin (), rbegin (), end () и rend ().

Это означает, что оператор присваивания:

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

делает недействительным delTitle.c_str().Это означает, что ваш delegates содержит кучу недопустимых указателей, и разыменование их вызывает неопределенное поведение.

Вы не получите сбой, потому что, скорее всего, один и тот же внутренний буфер используется повторно для всех вариантов строки.Это чистая удача, и с разными строками это может быть по-разному.Например, если строки становятся все больше и больше с каждой итерацией, тогда буфер будет перераспределяться, и ваши указатели будут указывать на некоторое количество мусора.

Правильнее всего будет хранить std::string вместо char *.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...