1

I am having a segmentation fault in the erase function of std::vector that is driving me crazy. Am having the following code:

std::map<uint32_t, std::vector<boost::uuids::uuid> >::iterator it
    = theAs.find(lSomeUint32);
if (it != theAs.end()) {
  std::vector<boost::uuids::uuid>& lIds = it->second; // vector contains one entry
  std::vector<boost::uuids::uuid>::iterator it2 = lIds.begin();
  while (it2 != lIds.end()) {
    if (*it2 == lSomeUuid) {
      lIds.erase(it2);
      break;
    }   
    ++it2;
  }   
}

In lIds.erase(it2), I get a segmentation fault. More precisely, I get a segmentation fault in _Orphan_range (can be found in c:\Program Files\Microsoft Visual Studio 10.0\VC\include\vector) that is called from erase. But I have no clue why. The vector and the iterator look ok. But in _Orphan_range, something goes completely wrong. The while loop in there is executed three time although my vector contains one item only. In the third run, the variable _Pnext gets broken.

Does someone have an idea? That would be awesome!

David


Unfortunately (or maybe fortunately), the example above executed standalone works. But inside my big software project, it doesn't work.

Does someone know what the failing function _Orphan_range is executed for?

3 Answers 3

2

Erasing from std::vector invalidates iterators. see STL vector::erase Therefore it2 is invalid after the first call to erase. Alas the check "(it2 != lIds.end()) " will not be true.

change your code to:

if (*it2 == lSomeUuid) {
  it2 = lIds.erase(it2);
  break;
}  
Sign up to request clarification or add additional context in comments.

2 Comments

As with most other crashes deep within someone else's code (when it's the STL or something similarly widely used and tested), it's probably a tricky problem in yours. and this one, if you aren't paying close attention, can very easily bite you. This is almost certainly your issue.
how your snippet differs from OP's one?
0

You compare with wrong end iterator.

std::vector<boost::uuids::uuid>::iterator it2 = lIds.begin();
while (it2 != pIds.end()) {

Note lIds and pIds. Try to use more letters in your variables names and don't use hungarian notation. You'd caught Ids_ptr almost instantly.

3 Comments

Oh dear. I made a mistake in the example. I changed it.
Now what you provided looks completely valid
Yes, I also looks good to me. I also tested it with valgrind on linux. It's strange.
-1

Isn't your

 "theAs.find(lSomeUint32);"

returning the index position rather than the Map::iterator? I'm not sure about this. Can you check it out? The find() function returns the position of the lSomeUint32 in theAs and would return the position of that lSomeUint32 in the string(if it is present). I suppose that is the reason why your erase function is throwing an error. It is not able to erase a data that is not present or that is not in the scope of your program.

Even otherwise if your find() returns the map object I would, in addition to that put a simple if structure to check whether that particular find() returns any object or is NULL just to make sure that the iterator is assigned a value before being operated.

Just a suggestion.

2 Comments

Can I know why is this a wrong answer? With the code snippet that was what I was able to infer.
Unfortunately (or maybe fortunately), the example above executed standalone works. But inside my big software project, it doesn't work. Does someone know what the failing function _Orphan_range is executed for?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.