mardi 3 janvier 2017

Why do I segfault while iterating over a list?

I'm creating an std::list<Consumer*>, passing that into a copy constructor, and iterating over that. When I check the size of the list it tells me the correct length (in my case 1) but when using the std::list<...>::iterator methods to iterate through all elements I segfault.

From what I can tell my list is being constructed properly but the iteration doesn't seem to behave.

main.cpp

//define all consumers
Logging log = Logging();

//put consumers in a list
std::list<Consumer*> c;
c.push_back( (Consumer*) &log); //polymorphism

//define producers
FlightInstrumentation flin = FlightInstrumentation(c);

//start the consumers
std::thread logthread(&Consumer::run, log);

//start the producers
std::thread flinthread(&Producer::run, flin);

logthread.join();
flinthread.join();

FlightInstrumentation.cpp

//ctor
FlightInstrumentation::FlightInstrumentation(std::list<Consumer*> &c) : Producer()
{
    consumers = new std::list<Consumer*>(c); //copy constructor
    printf("Size of list is %d\n", consumers->size()); //reports correct size
}

// main producer loop
void FlightInstrumentation::run()
{
    while(true) {
        printf("Size of list is %d\n", consumers->size()); //size is 1
        for( std::list<Consumer*>::iterator c = consumers->begin(); c != consumers->end(); ++c)
        {
            printf("Inside loop\n");
            //if we are able to update shared mem...
            if( (*c)->update_shared_memory(&sensor_data) ) //SEGFAULT
            {
                (*c)->notify(); //let the consumer know!
            }
        }
    }
}

This FlightInstrumentation loop prints

"Size of list is 1"
"inside loop"
"inside loop"
SEGFAULT

but it shouldn't print "inside loop" twice!

With GDB I looked at the loop contents and the second time it iterates c takes on the value of 0x11 (random) and I can't print it in GDB because it "has trouble accessing the variable". When I call (*c)->update_shared_memory() I segfault.

I put a break statement in the for loop to force it to execute only once and it works but when the destructor is called it fails and I get double tree free errors, telling me I might have free'd the same memory twice.

Aucun commentaire:

Enregistrer un commentaire