Search code examples
c++visual-studio-codeboostvisual-studio-2019centos8

Why does this code works on one platform but doesn't work on another?


I've written a long and complicated server program on windows. Used visual studio 2019.

Then I've created a CentOS 8 operating system on vm virtualbox and transferred all the code there. And rebuilt an executable with visual code. That works okay except one part.

Here is the code that causes the crash:

//clients is    std::map<int, boost::shared_ptr<Client>> clients;

        for (const auto& kv : clients) {
            
            int elapsed_seconds = boost::chrono::duration_cast<boost::chrono::seconds>(timeNow - kv.second->lastUpdated).count();

            int i = kv.first;

            if (elapsed_seconds >= ServerData::SessionTimeoutSeconds)
            {
                trash_bin.push_back(clients[i]);
                clients.erase(i);
            }
        }

this works without any bug on windows(compiled with visual studio 2019)

but gives this error on centos 8 (compiled with visual code / g++)

Assertion `px != 0' failed. Aborted (core dumped)

But if I put break; right after client.erase(i); problem is solved.

if (elapsed_seconds >= ServerData::SessionTimeoutSeconds)
{
    trash_bin.push_back(clients[i]);
    clients.erase(i);
    break;//this line makes it work.
}

So problem is caused when for loop iterates after deleting something from clients.

The question is :

Why does it solve this problem automatically, without breaking out of the loop on the code compiled on windows but cannot solve it on centos 8 ?


Solution

  • for (const auto& kv : clients) {
    

    This iterates over the range using iterators. After the loop body is executed each time, the iterator is incremented.

    int i = kv.first;
    clients.erase(i);
    

    This invalidates the current iterator. When the invalid iterator is incremented after the loop body, the behaviour of the program is undefined.


     break;//this line makes it work.
    

    Why does it solve this problem

    Because when you break out of the loop before the invalid iterator is incremented, there is no undefined behaviour.