assigning value from a vector (of shared pointer) to a shared pointer cause segmentation fault c++

Yotam Source

In my code, I have a vector <vector <vector <vector <std::tr1::shared_ptr<foo> > > > > named foosBoxes. The nested vector has a role of simulating a physical boxes position. I also have a while loop which cause a segmentation fault:

vector<std::tr1::shared_ptr<foo> >::iterator fooit = foosBoxes[x][y][z].begin(); //x,y,z are valid integer
std::tr1::shared_ptr<foo> aFoo;
while (fooit != foosBoxes[x][y][z].end()){
  aFoo = *fooit; //this cause segmentation fault
  fooit++;
  //some stuff which does not have an effect on fooit;
}

Some thing I have tried:
1. I have tried to use aFoo = *fooit++ but this didn't work.
2. The segmentation fault occurs roughly after several thousandths loops which went on fine.
3. I have tried to valgrind the problem and valgrind went through the step.
4. In the loop that crashes, I have printed a running counter before and after the suspected line. when before the line, I get 8 printings (the size of the vector) and when after I get 7 printings.

How can I figure this out?

Update:
I have added a loop to run before the main loop:

int kkk = 1214
int c = 0;
while (c < foosBoxes[x][y][z].end()){
   aFoo = foosBoxes[x][y][z][c++];
   printf("%i\t, kkk);
   fflush(stdout);
}

Which yields the same results.

Update:
according to gdb:

Program received signal SIGSEGV, Segmentation fault. 0x000000000043e400 in rotate (kkk=1214) at /usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/tr1/boost_shared_ptr.h:153 153 dispose();

I think that the appropriate function in boost_shared_ptr.h is

void
  release() // nothrow                                                                                                                      
  {
    if (__gnu_cxx::__exchange_and_add(&_M_use_count, -1) == 1)
      {
        dispose(); //this is line 153
#ifdef __GTHREADS
        _GLIBCXX_READ_MEM_BARRIER;
        _GLIBCXX_WRITE_MEM_BARRIER;
#endif
        if (__gnu_cxx::__exchange_and_add(&_M_weak_count, -1) == 1)
          destroy();
      }
  }

dispose() is defined elsewhere in the file:

  // dispose() is called when _M_use_count drops to zero, to release                                                                        
  // the resources managed by *this.                                                                                                        
  virtual void
  dispose() = 0; // nothrow  

Could it be that the reason is ill management of shared_ptr and I should switch back to regular pointer?

Update:
yet another test with similar result:

int kkk = 1214 int c = fooBoxes[x][y][z].size(); while (c >= 0){ aFoo = foosBoxes[x][y][z][c--]; printf("%i\t, kkk); fflush(stdout); }

This time the program crush in the third iteration. Should the problem was with wrong allocation, then the program should have crush in the first iteration (in the opposite direction the program crashes in the first iteration).

c++segmentation-faultwhile-loopshared-ptr

Answers

answered 7 years ago Nim #1

You're code as it is looks okay, the only thing I can think is that are x y z valid? operator[] does no bounds checking...

answered 7 years ago ks1322 #2

Run your code with libstdc++ in debug mode. It will do extra checks of iterators, containers and algorithms and hopefully will help to find the bug.

answered 7 years ago Shubhendu Sinha #3

To operate on an element of foosBoxes[x][y][z] you can also try:

while (fooit != foosBoxes[x][y][z].end()){
      vector<std::tr1::shared_ptr<foo> > *aFoo = *fooit; 
       fooit++;
      //To use the object 
     // use it as   aFoo->method()  
 }

Not sure if i am making the point. But i am currently using pointers to iterate in my objects.

answered 7 years ago Leo #4

//some stuff which does not have an effect on fooit;

But does the stuff have any effect on foosBoxes[x][y][z]? In particular does it remove elements or cause a vector relocation? If so, fooit cannot be compared meaningfully to foosBoxes[x][y][z].end().

Also, what happens to aFoo in the loop? If this gets an invalid value, an assignment to it later will cause undefined behaviour.

Try removing the some stuff from the loop. If that works the stuff contains a bug. If the loop still fails, the cause must be an invalid value in fooxBoxes[] before you enter the loop

I have no experience with ValGrind. But I have used similar products. Please check that you have configured ValGrind to its most strict settings. This might make using it painfully slow, but hopefully finds the bug.

answered 7 years ago Yotam #5

I have came to the conclusion that the problem was with the use vector is wrong since I update it through the code. I don't know how the memory management in c++ works but I believe that some sort of overlapping between two vector occurred. I have switched to set and everything works now

comments powered by Disqus