簡體   English   中英

迭代器在列表中無限循環

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM