2017-02-05 22 views
0

在下面的代碼片段中,我將Instruction的插入Function::iterator bs指向的BasicBlock。內循環遍歷這個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! 
    } 
} 
+0

我只是創建一個新的列表,並附加到它,而不是修改您正在迭代的集合。地圖/過濾器組合也可以工作。 – Carcigenicate

+0

'ReplaceInstWithValue'看起來像什麼? – 1201ProgramAlarm

+0

http://llvm.org/docs/doxygen/html/BasicBlockUtils_8cpp_source.html#l00189 – Shuzheng

回答

0

不幸的是,你沒有提供足夠的細節,但我強烈懷疑,你插入一個新元素放入容器中,現有的迭代器(其它元素)都是無效的這樣一種方式。這是許多容器類的常見行爲,例如std::vector<>::insert(),如果新的size()超過capacity()(否則只有存在於插入點之前的元素的迭代器保持有效),將使所有現有迭代器無效。

避免這種情況的方法是使用不受此問題影響的容器,例如,一個std::list<>,因爲std::list<>::insert()不會使任何現有的迭代器或引用無效。

+0

那麼你將如何解決這個問題? – Shuzheng