如何在插入元素后继续迭代数据结构?

时间:2017-02-05 17:56:25

标签: c++ c++11 iterator llvm

在下面的代码段中,我将Instruction插入BasicBlock指向的Function::iterator bs。内部循环遍历此BasicBlock中包含的指令。

现在,在内部循环插入这些指令之后,程序进入带有指令序列的无限循环:

and
mul
xor
and
mul
xor
and
mul
xor
and
mul
xor
and
mul
xor
and
mul 
...

如何插入迭代的数据结构,同时避免进入无限循环?

不知何故,迭代器变得疯狂(或者它被无效)。如何解决这个问题有一个共同的习惯用法吗?

for (Function::iterator bs = F.begin(), be = F.end(); bs != be; ++bs) {
    for (BasicBlock::iterator is = bs->begin(), ie = be->end(); is != ie; ++is) {
        Instruction& inst  = *is;
        BinaryOperator* binop = dyn_cast<BinaryOperator>(&inst);

        if (!binop) {
            continue;
        }

        unsigned opcode = binop->getOpcode();
        errs() << binop->getOpcodeName() << "\n";

        if (opcode != Instruction::Add) {
            continue;
        }

        IRBuilder<> builder(binop);
        Value* v = builder.CreateAdd(builder.CreateXor(binop->getOperand(0), binop->getOperand(1)), 
                                     builder.CreateMul(ConstantInt::get(binop->getType(), 2), 
                                                       builder.CreateAnd(binop->getOperand(0), binop->getOperand(1))));

        ReplaceInstWithValue(bs->getInstList(), is, v); // THINGS GO WRONG HERE!
    } 
} 

1 个答案:

答案 0 :(得分:0)

不幸的是,您未能提供足够的详细信息,但我强烈怀疑您是否将新元素插入到容器中,使现有迭代器(对其他元素)无效。这是许多容器类的通常行为,例如std::vector<>::insert(),如果新的size()超过capacity(),则会使所有现有的迭代器无效(否则在插入点之前只有元素的现有迭代器保持有效)。

避免这种情况的方法是使用不受此问题影响的容器,例如: std::list<>,因为std::list<>::insert()不会使任何现有的迭代器或引用无效。