I'm using an iterator in a for loop, and for some reason it is looping infinitely. It appears to be doing what it is supposed to be doing, though, just infinitely.
Looking at other similar questions did not help me solve my issue, as I am not using splice anywhere and tried many different ways of implementing this loop (for, while, using an int for the conditional loop, using the iterator itself, iterator advance, etc). The most progress I've had was getting an invalid read instead (see below).
I double checked the code to see if I wasn't manipulating iterator pointers directly (possibly generating a situation where list.end() = list.begin()) but couldn't find anything of the sort. All I used for this specific list was find, insert and clear.
I'm iterating through a list of pairs composed of struct pointer REG and an int. This is compiled in C++11 with -Wall and -Wextra.
The function that results in the infinite loop is:
int getAvailableColor(int K, std::list<std::pair<REG*, int>> adjacency){
std::list<std::pair<REG*, int>>::iterator it;
int colors[K];
std::memset(colors, 0, (K)*sizeof(int));
// This loops forever
for(it = adjacency.begin(); it != adjacency.end(); it++)
{
if((*it).second == 0){
if((*it).first->COLOR != -1)
{
colors[(*it).first->COLOR] = 1;
}
}
}
}
Modifying it with anything to control it to stop at the last item (using .size(), or checking to see if the same position of vector colors[] is already 1), results in an invalid read error. The code would be like below:
std::list<std::pair<REG*, int>>::iterator it;
int colors[K];
std::memset(colors, 0, (K)*sizeof(int));
it = adjacency.begin();
// This loops forever
for(int i = 0; i < adjacency.size(); i++)
{
if(i != 0){
std::advance(it, 1);
}
if((*it).second == 0){
if((*it).first->COLOR != -1)
{
colors[(*it).first->COLOR] = 1;
}
}
}
The function call is done here:
aux->COLOR = getAvailableColor(G.K, aux->ADJC);
The REG structure is:
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;
And the function that builds the list is:
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;
}
}
When I stop the infinite loop this is the valgrind output:
==2571== Process terminating with default action of signal 2 (SIGINT)
==2571== at 0x10CE68: __gnu_cxx::__aligned_membuf<std::pair<REG*, int> >::_M_ptr()
==2571== by 0x10C4DB: std::_List_node<std::pair<REG*, int> >::_M_valptr()
==2571== by 0x10BB44: std::_List_iterator<std::pair<REG*, int> >::operator*() const
==2571== by 0x10AF29: getAvailableColor(int, std::__cxx11::list<std::pair<REG*, int>, std::allocator<std::pair<REG*, int> > >)
==2571== by 0x10AC5A: runStack(GRAPH)
==2571== by 0x10A500: algorithm(GRAPH)
==2571== by 0x1105DE: main
And the error when more manually controlling the loop:
==2002== Invalid read of size 8
==2002== at 0x10D226: std::__cxx11::_List_base<std::pair<REG*, int>, std::allocator<std::pair<REG*, int> > >::_M_get_size() const
==2002== by 0x10C8A7: std::__cxx11::list<std::pair<REG*, int>, std::allocator<std::pair<REG*, int> > >::_M_node_count() const
==2002== by 0x10BDFB: std::__cxx11::list<std::pair<REG*, int>, std::allocator<std::pair<REG*, int> > >::size() const
==2002== by 0x10AF10: getAvailableColor(int, std::__cxx11::list<std::pair<REG*, int>, std::allocator<std::pair<REG*, int> > >)
==2002== by 0x10AC5A: runStack(GRAPH)
==2002== by 0x10A500: algorithm(GRAPH)
==2002== by 0x11070A: main
==2002== Address 0x1f00000011 is not stack'd, malloc'd or (recently) free'd
==2002==
==2002==
==2002== Process terminating with default action of signal 11 (SIGSEGV): dumping core
==2002== Access not within mapped region at address 0x1F00000011
==2002== at 0x10D226: std::__cxx11::_List_base<std::pair<REG*, int>, std::allocator<std::pair<REG*, int> > >::_M_get_size() const
==2002== by 0x10C8A7: std::__cxx11::list<std::pair<REG*, int>, std::allocator<std::pair<REG*, int> > >::_M_node_count() const
==2002== by 0x10BDFB: std::__cxx11::list<std::pair<REG*, int>, std::allocator<std::pair<REG*, int> > >::size() const
==2002== by 0x10AF10: getAvailableColor(int, std::__cxx11::list<std::pair<REG*, int>, std::allocator<std::pair<REG*, int> > >)
==2002== by 0x10AC5A: runStack(GRAPH)
==2002== by 0x10A500: algorithm(GRAPH)
==2002== by 0x11070A: main
I would appreciate any help! This is my first real try at C++ and I'm sure there's much I don't understand about the structures.
Aucun commentaire:
Enregistrer un commentaire