nnrales nnrales - 5 days ago 5
C++ Question

Segfault on inserting into std::vector with insert member function of std::vector

When I insert into the vector like this :

resVec.insert(frontIter , vec[idx]);


I get a seg fault , but if I do

*frontIter = vec[idx];


It works without any problems. I know that the []operator has the capacity to allocate space for the object and then insert it, is the error that insert does not allocate space and it needs the space to be already allocated when insert is called at a position ?

I think this error is due to my confusion about what this does :

vi vec(10);


Is this similar to
vec.resize(10)
or
vec.reserve(10)


Also does insert not work as say position 9 after I have called vec.reserve(10) ?

This is the code segment, just to make sure that I am not missing anything.

using vi = std::vector<int>;
using size = std::size_t;

// return vi after partition
vi partition_space(const vi & vec, size n)
{
vi resVec(vec.size());

int partVal = vec[n];
//resVec[n] = partVal;

// iterators to the back and front of the resVec.
// insertion will happen at the iters
vi::iterator frontIter = resVec.begin();
vi::reverse_iterator backIter = resVec.rbegin();

for(size idx = 0 ; idx < vec.size() ; ++idx)
{
if(idx == n)
{
continue;
}

if(vec[idx] < partVal) // insert in front of partVal
{
// *frontIter = vec[idx];
resVec.insert(frontIter , vec[idx]);
++frontIter;
}
else if(vec[idx] > partVal)// insert at back of n
{
*backIter = vec[idx];
++backIter;
}
else // repeated elements .. random choose to put it in front.. both choice does not matter
{
//resVec.insert(frontIter , vec[idx]);
*frontIter = vec[idx];
++frontIter;
}
}

frontIter++;

if(!std::distance(frontIter , backIter.base()))
{
std::cout << " ! " << std::endl;
}

*backIter = partVal;

return resVec ; // nrvo
}

Answer

Error is due to invalidation of iterator frontIter after first insert is happened. Here is whats going on:

  1. Code allocate vector vec with 10 elements in it.
  2. New element is inserted into position frontIter, this trigger vector storage re-allocation because vector out of it capacity so insert code reallocate inner storage to accommodate the insert. So this operation invalidate all vec iterators
  3. Code try to insert new element by using old (invalidated) iterator... - seg-fault!