c ++ list :: erase使用迭代器不能正常工作/奇怪的行为

时间:2014-03-05 17:00:34

标签: c++ c++11 iterator listiterator

目前我正在开发一种用于中断容忍网络的c ++路由协议。为此,它需要通过网络传播消息的副本(而不是消息本身)。为了在简单的模拟中测试其性能,我抽象了大多数因素,导致数据包被包含随机数据值,id,源和目标的简单结构模拟。

为了使这个协议起作用,我定义了以下类变量:

  1. std::list<packet> buffer - 此列表包含此节点可用于传输的所有数据包。
  2. std::list<packet*> toTransmit - 在2个或更多节点之间的每个联网机会,每个节点确定应传输哪些数据包,因此保留这个单独的指针列表
  3. std::list<packet*>::iterator priority_ix - 传输分两个阶段进行,第一个优先级数据包被传输,priority_ix跟踪toTransmit列表中的位置。
  4. std::list<packet*>::iterator normal_ix - 只有在所有优先级数据包都已发送后,才能正常传输开始,由此迭代器跟踪。
  5. 由于节点收到优先级数据包,它必须立即转发,priority_ix可能会重置到列表的开头,而正常传输需要从中断的地方继续,因此需要两个独立的迭代器

    现在为了奇怪的行为。通常我使用ix = mylist.erase(ix)删除我当前指向的项目,之后没有无效的迭代器。这一直对我有用,但是在我的代码中,某个特定方法似乎出现了问题。此方法处理收到的ACK消息,这可能导致删除这些迭代器中的任何一个(或两个)指向的数据包。

    void Node::receiveAck(u_int packet_id) {
        std::list<packet>::iterator ix = std::find(buffer.begin(), buffer.end(), packet_id);
        if(ix != buffer.end()) {
            if((**priority_ix) == packet_id && (**normal_ix) == packet_id) {
                priority_ix = toTransmit.erase(priority_ix);
                normal_ix = priority_ix;
            } else if((**priority_ix) == packet_id) {
                priority_ix = toTransmit.erase(priority_ix);
            }
            else if((**normal_ix) == packet_id) {
                normal_ix = toTransmit.erase(normal_ix);
            }
    
            else {
                toTransmit.remove(&(*ix));
            }
            buffer.erase(ix);
        }
    }
    

    这个方法应该做的是,它检查两个迭代器是否指向要删除的数据包,并确保在从toTransmitbuffer中丢弃数据包之前重新定位它们。顺便说一句,如果人们想知道,我已经编写了一个运算符==方法来比较带有u_ints的数据包,允许std::findbuffer中找到正确的数据包,我已经验证它确实进入了更正ix具有正确值的if语句。

    然而,反而发生的是,在调用std::list::erase函数时,它将迭代器递增到下一个有效位置,但实际上并未从列表中删除该元素,从而导致无效指针存储在{{ 1}}稍后在某处导致SEGFAULT。

    我试图通过在if语句中执行toTransmit和/或++priority_ix来解决此问题,然后在所有语句之后执行++normal_ix。这会很好地从toTransmit.remove(&(*ix))清除元素,但是如果递增的迭代器指向toTransmit中的最后一个元素,它将在递增后指向相同的元素而不是toTransmit ,再次导致SEGFAULTs在代码中的其他地方。

    奇怪的是,toTransmit.end()似乎正常工作。我对此问题感到非常沮丧,因为我经常使用迭代器,似乎从未遇到过这种行为。非常感谢您在代码中查看的任何帮助或方向。

0 个答案:

没有答案