[英]Iterator in for looping infinitely through list
我在 for 循環中使用迭代器,由於某種原因它無限循環。 它似乎在做它應該做的事情,雖然,只是無限的。
查看其他類似的問題並沒有幫助我解決我的問題,因為我沒有在任何地方使用 splice 並嘗試了許多不同的方法來實現這個循環(for,while,使用 int 作為條件循環,使用迭代器本身,迭代器提前, ETC)。 我取得的最大進展是讀取無效(見下文)。
我仔細檢查了代碼,看看我是否沒有直接操作迭代器指針(可能會產生 list.end() = list.begin() 的情況),但找不到任何類似的東西。 我用於這個特定列表的只是查找、插入和清除。
我正在遍歷由結構指針 REG 和一個 int 組成的對列表。 這是在 C++11 中使用 -Wall 和 -Wextra 編譯的。
用任何東西對其進行修改以控制它在最后一項處停止(使用.size(),或檢查矢量顏色[] 的相同 position 是否已經為 1),會導致無效讀取錯誤。
int getAvailableColor(int K, std::list<std::pair<REG*, int>> adjacency)
{
std::list<std::pair<REG*, int>>::iterator it;
int Ko = K;
int colors[K];
for(int i = 0; i < Ko; i++)
{
colors[i] = -1;
}
// This loop either breaks or runs forever... In some iterations
// At this point K is as was passed as parameter
for(auto it : adjacency)
{
if(it.second == 0){
if(it.first->COLOR != -1)
{
colors[it.first->COLOR] = 1;
}
}
}
// At this point K is decreased
for(int i = 0; i < Ko; i++)
{
if(colors[i] == -1) { return i; }
}
return -1;
}
顯然,刪除數組修改
colors[(*it).first->COLOR] = 1;
撤消無限循環問題(不幸的是也撤消了算法,因此不是解決方案)。 此外,這條線似乎在某種程度上減少了 integer K。
function 調用在這里完成:
aux->COLOR = getAvailableColor(G.K, aux->ADJC);
其中 aux 是一個 REG* 而 ADJC 是一個列表 (REG*, int)。 REG結構是:
typedef struct REG{
int ID;
int TYPE; // 0 - Physical, 1 - Virtual
int COLOR;
int CONN;
std::list<INTERF> INTRFR;
std::list<std::pair<REG*, int>> ADJC;
bool operator > (const REG& reg) const { return (CONN > reg.CONN); }
bool operator < (const REG& reg) const { return (CONN < reg.CONN); }
bool operator == (const REG& reg) const { return (ID == reg.ID); }
}REG;
INTERF typedef 是 std::pair(int, int),構建列表的 function 是:
void setAdjacency(GRAPH g)
{
std::list<REG*>::iterator it;
std::list<INTERF>::iterator it2;
std::list<REG*>::iterator it3 ;
REG* aux = newReg(-1, -1, " ");
REG* aux2;
int count;
for(it = g.LOGREG.begin(); it != g.LOGREG.end(); it++)
{
count = 0;
(*it)->ADJC.clear();
for(it2 = (*it)->INTRFR.begin(); it2 != (*it)->INTRFR.end(); it2++)
{
count++;
aux2 = getRegister(g.REGISTERS, it2->first);
(*it)->ADJC.insert((*it)->ADJC.end(), std::pair<REG*, int>(aux2, 0));
}
(*it)->CONN = count;
}
}
當我停止無限循環時,這是 valgrind output:
==13369== Process terminating with default action of signal 2 (SIGINT)
==13369== at 0x10D008: __gnu_cxx::__aligned_membuf<std::pair<REG*, int> >::_M_ptr()
==13369== by 0x10C67B: std::_List_node<std::pair<REG*, int> >::_M_valptr()
==13369== by 0x10BD18: std::_List_iterator<std::pair<REG*, int> >::operator*() const
==13369== by 0x10B116: getAvailableColor(int, std::__cxx11::list<std::pair<REG*, int>, std::allocator<std::pair<REG*, int> > >)
以及無效的讀取錯誤:
==13520== Invalid read of size 8
==13520== at 0x10BFE3: std::_List_iterator<std::pair<REG*, int> >::operator++()
==13520== by 0x10B159: getAvailableColor(int, std::__cxx11::list<std::pair<REG*, int>, std::allocator<std::pair<REG*, int> > >)
==13520== by 0x10AE10: runStack(GRAPH)
==13520== by 0x10A500: algorithm(GRAPH)
==13520== by 0x1107AC: main
==13520== Address 0x10520fb40 is not stack'd, malloc'd or (recently) free'd
==13520==
==13520==
==13520== Process terminating with default action of signal 11 (SIGSEGV): dumping core
==13520== Access not within mapped region at address 0x10520FB40
==13520== at 0x10BFE3: std::_List_iterator<std::pair<REG*, int> >::operator++()
==13520== by 0x10B159: getAvailableColor(int, std::__cxx11::list<std::pair<REG*, int>, std::allocator<std::pair<REG*, int> > >)
我將不勝感激任何幫助。 這是我在 C++ 的第一次真正嘗試,我確信我對這些結構有很多不了解的地方。
編輯:按照建議使用 auto 似乎至少在第一次測試中停止了無限循環。 當我這樣做時,我還注意到 K 的值在循環之前和之后之間發生了變化。 制作“備份”變量解決了它。 但是,在某些測試中仍然會發生無效讀取錯誤和無限循環(相同的結構只是不同的輸入)。 相應地更新上面的代碼。
EDIT2(已解決):無限循環已解決,將數組替換為向量,無效讀取錯誤是一個實現邏輯問題(K 在每次迭代時遞減,因此即使最初 COLOR 僅與 K-1 一樣大,與每次迭代都有一個更大的溢出)。 謝謝大家!謝謝:)
關於迭代器的代碼看起來並沒有特別錯誤。
確保在此指令中您沒有越界訪問數組:
colors[(*it).first->COLOR] = 1;
這是您的問題的最可能原因。
但是,由於您沒有修改迭代器,也不要在循環之外訪問它,我建議您使用增強的 for 循環語法。 而不是: for(it = adjacency.begin(); it.= adjacency;end(); it++)
您可以輕松替換為:
for (auto it: adjacency)
除非您必須與 C++03 兼容。 這將使您免於許多愚蠢的錯誤。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.