473,398 Members | 2,525 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,398 software developers and data experts.

vector.erase() ?

BCC
I have the following code, where good_list is a vector of CUnits:

int high_cutoff = 10;
vector<CUnit>::iterator it;
for (it = good_list.end(); it != good_list.begin(); --it) {
CUnit* ccu = it;
if (ccu->GetCutoff() >= high_cutoff) {
good_list.erase(it);
}
}

Doesn't give any errors, but also does not seem to be removing the element
correctly from good_list.

There something wrong with the above code?

Thanks
Jul 22 '05 #1
9 3356
BCC wrote:
I have the following code, where good_list is a vector of CUnits:

int high_cutoff = 10;
vector<CUnit>::iterator it;
for (it = good_list.end(); it != good_list.begin(); --it) {
Note that good_list.end() is an iterator that you can't do much with.
Dereferencing it is an error. If you really need to go backwards, you
probably want to use reverse iterators instead.
CUnit* ccu = it;
This may be an invalid conversion. An implementation may or may not
implement vector iterators as plain pointers. There's not really any
reason to need a pointer when you've already got an iterator. Just use
the iterator.
if (ccu->GetCutoff() >= high_cutoff) {
One problem is that ccu isn't valid the first time through.
good_list.erase(it);
'it' is no longer valid after this. I don't know if you are allowed to
apply -- to it. I don't think this is your problem, but you should
probably do something like this:

for (/* init */; /* cond */; /* EMPTY! */)
if (/* condition */)
it = good_list.erase(it);
else
++it;

I'm using ++ instead of --, figuring that you'll want to use reverse
iterators.
}
}

Doesn't give any errors, but also does not seem to be removing the element
correctly from good_list.

There something wrong with the above code?


Yup.

Here's the entire replacement I'd recommend (untested):

int high_cutoff = 10;
vector<CUnit>::reverse_iterator it;
for (it = good_list.rbegin(); it != good_list.rend(); ) {
if (it->GetCutoff() >= high_cutoff) {
it = good_list.erase(it);
}
else {
++it;
}
}

-Kevin
--
My email address is valid, but changes periodically.
To contact me please use the address from a recent posting.
Jul 22 '05 #2
BCC
>
Here's the entire replacement I'd recommend (untested):

int high_cutoff = 10;
vector<CUnit>::reverse_iterator it;
for (it = good_list.rbegin(); it != good_list.rend(); ) {
if (it->GetCutoff() >= high_cutoff) {
it = good_list.erase(it);
}
else {
++it;
}
}


Makes sense.... but one problem is that erase() returns an iterator, not a
reverse_iterator...

Ill see if I can iron it out, thanks!
B
Jul 22 '05 #3
BCC wrote:
Here's the entire replacement I'd recommend (untested):

int high_cutoff = 10;
vector<CUnit>::reverse_iterator it;
for (it = good_list.rbegin(); it != good_list.rend(); ) {
if (it->GetCutoff() >= high_cutoff) {
it = good_list.erase(it);
}
else {
++it;
}
}

Makes sense.... but one problem is that erase() returns an iterator, not a
reverse_iterator...


Oh, yeah...

Well, that was kind of dumb, actually. You don't even *want* the
iterator returned by erase of you are going backward. Make them forward
iterators instead - there's no obvious reason to go backward.

On the other hand, if there *is* a reason that you need to go backward,
which just isn't apparent to me, then you can do something like this:

vector<CUnit>::reverse_iterator tmp = it;
++tmp;
good_list.erase(it);
it = tmp;

inside the 'if' block.

Another alternative is to use algorithms. std::remove_if should work, I
think. But remember that it doesn't really remove anything, it just
shuffles the "removed" elements to the end for you to erase().

-Kevin
--
My email address is valid, but changes periodically.
To contact me please use the address from a recent posting.
Jul 22 '05 #4
"Kevin Goodsell" <us*********************@neverbox.com> wrote:
On the other hand, if there *is* a reason that you need to go backward,
which just isn't apparent to me, then you can do something like this:

vector<CUnit>::reverse_iterator tmp = it;
++tmp;
good_list.erase(it);
it = tmp;

inside the 'if' block.


You can also say:

good_list.erase(it++);

This is safe because the variable "it" is incremented while it is still
valid; see:

http://mail.worldforge.org/pipermail...er/000168.html

(code near the bottom of the page)

David F
Jul 22 '05 #5
David Fisher wrote:
"Kevin Goodsell" <us*********************@neverbox.com> wrote:

On the other hand, if there *is* a reason that you need to go backward,
which just isn't apparent to me, then you can do something like this:

vector<CUnit>::reverse_iterator tmp = it;
++tmp;
good_list.erase(it);
it = tmp;

inside the 'if' block.

You can also say:

good_list.erase(it++);


Yeah, if they are reverse iterators. That whole going backwards thing
got me confused. This method doesn't work if 'it' is a regular (not
reverse) iterator though, because the erase would invalidate the new
value of 'it'.

This is safe because the variable "it" is incremented while it is still
valid; see:

http://mail.worldforge.org/pipermail...er/000168.html

(code near the bottom of the page)


That is a bit different because the container is a std::list. In that
case, no iterators are invalidated by the erase, so the method you
showed should be safe whether it's a reverse iterator or not.

-Kevin
--
My email address is valid, but changes periodically.
To contact me please use the address from a recent posting.
Jul 22 '05 #6
"Kevin Goodsell" <us*********************@neverbox.com> wrote:
David Fisher wrote:
You can also say:

good_list.erase(it++);


Yeah, if they are reverse iterators. That whole going backwards thing
got me confused. This method doesn't work if 'it' is a regular (not
reverse) iterator though, because the erase would invalidate the new
value of 'it'.


It works in either direction - post increment operators do something like
this:

temp = (the next value after x);
someFunction(x);
x = temp;

The increment is not applied to the invalidated iterator, it is applied to
the original value. It does not do this:

someFunction(x);
x = (the next value after x);

If you write your own post increment operator, you need to return a value
and not a reference to "this", because of these semantics.

David F
Jul 22 '05 #7
David Fisher wrote:
"Kevin Goodsell" <us*********************@neverbox.com> wrote:

David Fisher wrote:
You can also say:

good_list.erase(it++);
Yeah, if they are reverse iterators. That whole going backwards thing
got me confused. This method doesn't work if 'it' is a regular (not
reverse) iterator though, because the erase would invalidate the new
value of 'it'.

It works in either direction - post increment operators do something like
this:


I think you misunderstand. The container in question is a vector.
erase() on a vector invalidates all iterators to elements that follow
the erased element(s).

temp = (the next value after x);
someFunction(x);
In the specific case we are talking about (where someFunction is the
vector erase() function, or calls that function), temp becomes invalid
here...
x = temp;


....and therefore this is a problem. Maybe. I'm not actually sure what
the restrictions on invalidated iterators are.

-Kevin
--
My email address is valid, but changes periodically.
To contact me please use the address from a recent posting.
Jul 22 '05 #8
"Kevin Goodsell" <us*********************@neverbox.com> wrote:
I think you misunderstand. The container in question is a vector.
erase() on a vector invalidates all iterators to elements that follow
the erased element(s).

temp = (the next value after x);
someFunction(x);


In the specific case we are talking about (where someFunction is the
vector erase() function, or calls that function), temp becomes invalid
here...
x = temp;


...and therefore this is a problem. Maybe. I'm not actually sure what
the restrictions on invalidated iterators are.


Sorry, I was focusing on the wrong thing (the iterator rather than the
container) - I think you're probably right.

David F
Jul 22 '05 #9
> ...and therefore this is a problem. Maybe. I'm not actually sure what
the restrictions on invalidated iterators are.

This is more of a question than a suggestion but given that it's a vector
and the reallocation happening on an erase() call, would this be any less
efficient:

int high_cutoff = 10;
vector<CUnit> temp;
size_t VSize = CUnit.size();
temp.reserver(VSize());
for(size_t i = 0; i < VSize; ++i) {
if(CUnit[i].GetCutoff() < high_cutoff) temp.push_back(CUnit[i];
}
if(!temp.empty()) CUnit.swap(temp);
Jul 22 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
by: Steve Hill | last post by:
Hi, suppose I have a vector allocated on the heap. Can I use a temporary (stack based vector) and swap to clear it, or is this unsafe. e.g. vector<int> *v; vector<int> tmp; v->swap(tmp); // is...
3
by: Jonathan | last post by:
Hey again everyone! I have another question for you guys. I am trying to erase a certain vector element based on what number the user selects. Here is what I did: case 'b' : { cout << "Please...
9
by: david wolf | last post by:
I want to delete all even numbers in a vector, I am not sure if there's any better way to do it. Following program is how I did it. Look at the part of code beginning from comments: //delete all...
5
by: Billy Patton | last post by:
I have a polygon loaded into a vector. I need to remove redundant points. Here is an example line segment that shows redundant points a---------b--------c--------d Both b and c are not...
14
by: cayblood | last post by:
I want to iterate through a vector and erase elements that meet a certain criteria. I know there is an algorithmic way of doing this, but first I would like to know how to do it with normal...
9
by: Amadeus W. M. | last post by:
I have a vector from which I want to erase elements between iterators i,j. If i<j, everything works as expected, but if j>i, an insertion is actually performed. Example: vector<double> x(10);...
4
by: Christian Bruckhoff | last post by:
Hi. Is there a possibility to delete elements out of a vector? At the moment i do it by copying all needed elements to another vector. After clearing the old vector i copy them back element by...
3
by: =?iso-8859-1?q?Erik_Wikstr=F6m?= | last post by:
I have some code where there's this vector of pointers to objects and I need to delete and erase some of them, the problem is that to know which I need to iterate through the vector and I'm trying...
10
by: arnuld | last post by:
WANTED: /* C++ Primer - 4/e * * Exercise: 9.26 * STATEMENT * Using the following definition of ia, copy ia into a vector and into a list. Use the single iterator form of erase to...
3
by: chsalvia | last post by:
I have a question about the design of STL vector. One thing I wonder was why the STL designers chose to have the insert() and erase() functions take an iterator as the first argument, rather than...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.