Vector element erase cause SIGSEGV

B

Bin Chen

Hi,

I don't know what's wrong with my program, it causes SIGSEGV:

#include <vector>

using namespace std;

int main(void)
{
vector<int> v;
vector<int>::iterator iter;

int i,j,k;

i = 9;j = 10;k = 11;

v.push_back(i);
v.push_back(j);
v.push_back(k);

for (iter = v.begin();iter != v.end(); ++iter) {
printf("*********%d\n", *iter);
iter = v.erase(iter);
}

return 0;
}

Thanks.
ABAI
 
T

Thomas Tutone

Bin said:
I don't know what's wrong with my program, it causes SIGSEGV:

#include <vector>

using namespace std;

int main(void)
{
vector<int> v;
vector<int>::iterator iter;

int i,j,k;

i = 9;j = 10;k = 11;

v.push_back(i);
v.push_back(j);
v.push_back(k);

for (iter = v.begin();iter != v.end(); ++iter) {

Change the above line to:

for (iter = v.begin();iter != v.end();) {
printf("*********%d\n", *iter);
iter = v.erase(iter);
}

return 0;
}

std::vector::erase returns an iterator to the element immediately
following the one that was erased. So in effect, the expression "iter
= v.erase(iter)" causes iter to to be incremented. But your for loop
also increments iter. In other words, iter is incremented _twice_ each
time through the loop. The first time through the loop, iter begins
pointing to v[0] and ends pointing to v[2]. The second time through
the loop, iter begins pointing to v[2]. After printing the value of
v[2], the program erased v[2], and increments iter so that it is equal
to v.end(). Then, the program attempts to increment iter again (as
happens every time through your for loop), leading to undefined
behavior - in this instance, a seg fault.

To fix your program, change the line indicated above.

Best regards,

Tom
 
G

Guang Han

"Bin Chen дµÀ£º
"
Hi,

I don't know what's wrong with my program, it causes SIGSEGV:

#include <vector>

using namespace std;

int main(void)
{
vector<int> v;
vector<int>::iterator iter;

int i,j,k;

i = 9;j = 10;k = 11;

v.push_back(i);
v.push_back(j);
v.push_back(k);

for (iter = v.begin();iter != v.end(); ++iter) {
printf("*********%d\n", *iter);
iter = v.erase(iter);
erase will return the next element after the iter. assuming you are
erasing the last element, then iter will be v.end (), and then in your
for loop you'll still ++iter, so it should be some errors.....
 
H

Haro Panosyan

If the question can be reformulated as how to fix,
then this is something you need to do

int Size = v.size();
for (int I = 0; I < Size; I++) {
printf("*********%d\n", *v.begin());
v.erase(v.begin());
}


If you want really to know why it is not working,
this may give you a hint:


for (iter = v.begin();iter != v.end(); ++iter) {
printf("BEF *********%d\n", *iter);
iter = v.erase(iter);
printf("AFT *********%d\n", *iter);
}

Erasing any element except the last causes the vector to
be "rearanged", and return value is iterator to next element.
Erasing the last element seems not to return v.end() in my tests,
but returns the last element and this could be because the pointer
to the last location is in memory.

-haro
 
N

Nate Barney

Thomas said:
for (iter = v.begin();iter != v.end();) {

printf("*********%d\n", *iter);
iter = v.erase(iter);
}

I would be tempted to write the loop this way:

for (iter = v.begin(); iter != v.end(); iter = v.erase(iter))
printf("*********%d\n", *iter);

Does anyone care to comment on whether or not this is good style?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,962
Messages
2,570,134
Members
46,690
Latest member
MacGyver

Latest Threads

Top