vendredi 30 août 2019

Iteration through std::vector seems to be broken in only one function

I have a vector of struct elements and in one function, when iterating through it, differente errors related to bound are thrown.

I am implementing an UDP Server-client connection where some messages must be acknowledged. I implement a vector of struct elements where each contains the message sent, and the time in milliseconds it was sent. I don't think this is really relevant, for I have tried the same function storing a std::string instead of the struct, but, just in case.

When I receive an ACK message, I iterate through this vector with no problem at all:

///WORKING CODE IN OTHER FUNCTIONS
auto it = mACKExpected.begin();
for (; it != mACKExpected.end(); it++)
{
    if (it->msg.msgCount() == count)
    {
        break;
    }
}

However, I have a separate method connected to a QTimer timeout that checks if an acknowledgeable message sent more than a second ago has not been acknowledged yet:

///CODE 1
for (auto it = mACKExpected.begin();it!=mACKExpected.end();)
{
    if ((curTime - it->millis) > mquiMsgTimeout)
    {
        debug() << "Message" << it->msg.raw() << "(count: " << it->msg.msgCount() << ") not acknowledged.";
        send(QtStrMsg::newMsg(it->msg.msgType(), getCount(), it->msg.msgData()).raw());
    }
    ++it;
}

I have also tried by iterating as:

///CODE 2
for (auto it : mACKExpected)
{
    if ((curTime - it.millis) > mquiMsgTimeout)
    {
        debug() << "Message" << it.msg.raw() << "(count: " << it.msg.msgCount() << ") not acknowledged.";
        send(newMsg(it.msg.msgType(), getCount(), it.msg.msgData()).raw());
    }
}

Also by using const iterators, but there are always errors. In the CODE 1 example, a "can't increment vector iterator past end" exception is thrown in the ++it; line. In the last code, an std::bad_alloc{} instead, but in the for(... line. If I erase the current iterator by doing this:

if ((curTime - it->millis) > mquiMsgTimeout)
    {
        debug() << "Message" << it->msg.raw() << "(count: " << it->msg.msgCount() << ") not acknowledged.";
        send(QtStrMsg::newMsg(it->msg.msgType(), getCount(), it->msg.msgData()).raw());
        it=mACKExpected.erase(it);
    }
else
    ++it;

a "vector erase iterator outside range" error is risen in the erase line.

What can I do? I have been stuck with this for two days. I have tried using QVector instead, but the same problem occurs. It seems to me that something gets broken when calling this function, but I don't know what else to try. Thanks.

Aucun commentaire:

Enregistrer un commentaire