jeudi 30 mars 2017

Iterator referencing to nothing on 8th element PLF::Colony

I am having an interesting issue. For starters, I am currently developing a 2D geometry editor where the user is able to draw lines and arcs. In order to draw a line and arc, the user needs to select 2 nodes.

In an earlier question on the forum, I was wondering if there was anything available that will not invalidate pointers when elements are erased (or inserted) but is not an std::list (for various reasons that are scattered throughout stack overflow). A user recommended that I take a look at the plf::colony class. Which, in short, acts like std::list but has the speed of std::deque in many instances.

Anyways, I am implementing this class in my program to contain the nodes, lines, and arcs. I was able to successfully integrate the class and everything builds. However, I notice that there is a bug in my bug when I go to delete nodes.

I have narrowed down the issue to be this: If I create less then 10 nodes, my code is able to delete all of the nodes without an issue. However, if I select all of the 10 nodes, my program crashes. If I draw 20 nodes and select 10 of them for deletion, my program crashes. If I draw 15 nodes and select 5 of them, everything is good. If I draw 15 nodes and select 7 of them, everything is fine. If I draw 15 nodes and select 8, the program crashes. If I draw 50 nodes and select 8 for deletion, the program crashes. There is something about the 8th node that appears to crash the program.

Later, I stepped through the code (that I have posted below) and everything is fine until the iterator reaches the 8th item. There, the iterator points to nothing and crashes the program. The program crashes when it tries to erase the iterator from the colony.

I was wondering if anyone else using plf::colony ran into the same issue and what they did to fix the bug? Or is there something wrong with the way that I am setting up my code?

  if(_editor.getNodeList()->size() > 1 && _nodesAreSelected)
    {
        plf::colony<node>::iterator stopIterator = _editor.getNodeList()->end();
        for(plf::colony<node>::iterator nodeIterator = _editor.getNodeList()->begin(); nodeIterator != _editor.getNodeList()->end(); ++nodeIterator)
        {
            if(nodeIterator->getIsSelectedState())
            {
                if(_editor.getLineList()->size() > 1)
                {
                    /* Need to cycle through the entire line list and arc list in order to determine which arc/line the node is associated with and delete that arc/line by selecting i.
                     * The deletion of the arc/line occurs later in the code*/

                    for(plf::colony<edgeLineShape>::iterator lineIterator = _editor.getLineList()->begin(); lineIterator != _editor.getLineList()->end(); ++lineIterator)
                    {
                        if(*lineIterator->getFirstNode() == *nodeIterator || *lineIterator->getSecondNode() == *nodeIterator)
                        {
                            lineIterator->setSelectState(true);
                        }
                    }
                }


                if(_editor.getArcList()->size() > 0)
                {
                    for(plf::colony<arcShape>::iterator arcIterator = _editor.getArcList()->begin(); arcIterator != _editor.getArcList()->end(); ++arcIterator)
                    {
                        if(*arcIterator->getFirstNode() == *nodeIterator || *arcIterator->getSecondNode() == *nodeIterator)
                        {
                            arcIterator->setSelectState(true);
                        }
                    }
                }

                int size = _editor.getNodeList()->size();

                if(_editor.getNodeList()->size() <= 1 && _editor.getNodeList()->begin()->getIsSelectedState())
                {
                    if(_editor.getNodeList()->size() == 1)
                        _editor.getNodeList()->clear();
                    break; 
                }

               _editor.getNodeList()->erase(nodeIterator);
            }
        }
    }
    else if(_editor.getNodeList()->size() == 1 && _editor.getNodeList()->begin()->getIsSelectedState())
    {
        _editor.getNodeList()->clear();
    }

Aucun commentaire:

Enregistrer un commentaire