DormoTheNord
DormoTheNord

Reputation: 999

map/set iterator not derefrencable runtime error

I'm trying to run this function:

os::TMXTileset* os::TMXMap::getTilesetFromGid(int gid)
    {
        TMXTileset* tileset;
        std::map<std::string, TMXTileset>::iterator it;
        std::map<std::string, TMXTileset>::iterator comp;

        for (it=tilesetMap.begin(); it != tilesetMap.end(); it++)
        {
            comp = it;
            comp++;
            if ((gid >= it->second.getFirstGid()) && (gid < comp->second.getFirstGid()))
            {
                return &it->second;
            }
        }
        tileset = &it->second;
        return tileset;
    }

..but it is giving me this error:

"map/set iterator not derefrencable"

My first thought was to stop dereferencing it (using it->second instead of (*it).second), but that didn't change anything at all.

Any ideas?

Upvotes: 0

Views: 560

Answers (2)

Tobias Langner
Tobias Langner

Reputation: 10808

you first copy it, then you advance the copy and then you dereference the copy. This means you dereference end() whenever it is on the element before the last element.

You can easily test this on a map with 1 entry only - it should always fail to dereference comp.

you should do something like:

TMXTileset* tileset;
std::map<std::string, TMXTileset>::iterator it;
std::map<std::string, TMXTileset>::iterator comp;

for (it=tilesetMap.begin(); /*it != tilesetMap.end() can be ommited due to check for comp */; it++)
{
    comp = it;
    comp++;
    if (comp == tilesetMap.end())
    {
       break;
    }
    ...
}

Upvotes: 3

JohnB
JohnB

Reputation: 13713

Your for loop runs beyond the end of the map if it is not interrupted, so your third-last line will fail.

Upvotes: 0

Related Questions