我在for循环中使用迭代器,由于某种原因,它无限循环。但是,它似乎正在无限地进行它应该做的事情。
看看其他类似的问题并没有帮助我解决问题,因为我没有在任何地方使用拼接,而是尝试了许多不同的方式来实现此循环(例如,将int用于条件循环,使用迭代器本身,迭代器前进等)。我获得的最大进步是获得了无效的读取(见下文)。
我仔细检查了代码,看看是否没有直接操作迭代器指针(可能会产生list.end()= list.begin()的情况),但找不到任何类似的东西。我用于此特定列表的全部是查找,插入和清除。
我正在遍历由结构指针REG和一个int组成的对的列表。这是在C ++ 11中用-Wall和-Wextra编译的。
对其进行任何修改以使其停止在最后一项(使用.size()或检查矢量colors []的相同位置是否已经为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;
取消无限循环问题(不幸的是也取消算法,因此不是解决方案)。另外,似乎这条线以某种方式减小了整数K。
函数调用在这里完成:
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),构建列表的函数是:
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输出:
==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一样大,每次迭代都产生较大的溢出)。非常感谢大家:)
答案 0 :(得分:3)
有关迭代器的代码看起来并不特别错误。
请确保您不会在此说明中超出范围访问数组:
colors[(*it).first->COLOR] = 1;
这是造成您问题的最可能原因。
但是,由于您没有修改迭代器,也不要在循环外访问它,所以我建议您使用增强的for循环语法。
代替:
for(it = adjacency.begin(); it != adjacency.end(); it++)
您可以轻松地替换为:
for (auto it: adjacency)
除非您必须与C ++ 03兼容。
这样可以避免许多愚蠢的错误。