user1790374
user1790374

Reputation: 11

C++ Segmentation Fault when Iterating through a Vector

I have a program that maintains an integer vector. I have three functions that add an integer, remove an integer and check whether an integer is already in the vector. The problem is with the last one.

vector<int> children;
void CtpTestingApplication::addChild(int child)
{
    for (int i=0; i<children.size(); i++)
    {
    //already a child
    if (children[i]==child)
        return;
    }
    //child not yet recorded
   children.push_back(child);
   cout<<"added child "<<child;
}

void CtpTestingApplication::removeChild(int child)
{
   for (int i=0; i<children.size(); i++)
   {
    //already a child, remove it
    if (children[i]==child)
    {
        children.erase(children.begin()+i);
        cout<<"removed child "<<child;
    }
   } 
   //not recorded, no need to remove
}

bool CtpTestingApplication::isChild(int child)
{
   vector<int>::iterator ic;
   bool result = false;
   for (ic= children.begin(); ic < children.end(); ic++)
   {
     cout<<*ic<<" vs "<<child;
  //     if (child==*ic)
         result = true;
   }
   return result;
}

I always get segmentation fault when I uncomment "if (child==*ic)", even though printouts show that the vector is not empty and contains the expected integers.

For example, with the if statements commented, I can see 1 vs 4, 2 vs 4, 4 vs 4, 12 vs 4

I also attempted looping using children[i] and so on, but to no avail. Any help would be appreciated. Thank you.

Upvotes: 1

Views: 1447

Answers (2)

sashang
sashang

Reputation: 12184

Your loop should change from this:

   for (ic= children.begin(); ic < children.end(); ic++)

to this:

  for (ic= children.begin(); ic != children.end(); ic++)

This won't solve the problem because the container used is a vector and taking the difference between iterators of vectors is defined for that container class. However, it's still good practice to prefer,

ic != container.end()

because that will work for containers that lack that definition.

Upvotes: 2

Rody Oldenhuis
Rody Oldenhuis

Reputation: 38032

As John3136 indicated, the only potential problem I see is with the removeChild function. Try re-writing it like so:

void CtpTestingApplication::removeChild(int child)
{
   int i=0; 
   while (i<children.size())
   {         
      if (children[i]==child) {
         children.erase(children.begin()+i);             
         continue;
      }
      i++;
   }        
}

Why you get the segfault is anyone's guess. One possibility is that the removeChild() can be called inside some other thread, invalidating your iterator in isChild(). This would only be possible if you are using threads without proper mutexing (in which case you have a far bigger problem :)

Upvotes: 1

Related Questions