473,406 Members | 2,954 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,406 software developers and data experts.

Query regarding iterators and vector

I am new STL programming.
I have a query regarding vectors. If I am iterating over a vector
using a iterator, but do some operations that modify the size of the
vector. Will the iterator recognize this?

I wrote the following program to test this out.

#include <fstream>
#include <iostream>
#include <string>
#include <vector>

using namespace std;

int main()
{
vector<inta;

a.push_back(1);
a.push_back(2);
a.push_back(3);
cout<<"Vector test begin"<<endl;
vector<int>::iterator iter0;
for(iter0=a.begin(); iter0!=a.end(); iter0++)
{
cout << "\n value: " << (*iter0)<<endl;
if(*iter0 == 2)
{
a.push_back(4);
a.push_back(5);
}
}
cout<<"Vector test end";
}

I am getting the following output. Could somebody please explain what
is happening in my program. I am thoroughly confused.

---------------------------------------Output------------------
Vector test begin

value: 1

value: 2

value: 3

value: 4

value: 0

value: 41

value: 1

value: 2

value: 3

value: 4

value: 5

value: 4

value: 5
Vector test end

----------------------------------------------End of
Output--------------------------------------
Jul 4 '08 #1
13 1882
Sam
pr**********@gmail.com writes:
I am new STL programming.
I have a query regarding vectors. If I am iterating over a vector
using a iterator, but do some operations that modify the size of the
vector. Will the iterator recognize this?
No. An insertion or deletion in a std::vector invalidates all existing
iterators.

Use std::list if you want iterators to remain valid after an insertion (or a
deletion, if the iterator does not point to the std::list member that was
deleted).
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)

iEYEABECAAYFAkhuo3oACgkQx9p3GYHlUOLeyACfUNo/pQKJ4Bt8lX36K0KysbUG
5zYAn2o9oKalz38aDj3p69vXn+PLsz/f
=7gEI
-----END PGP SIGNATURE-----

Jul 4 '08 #2
pr**********@gmail.com wrote:
I am new STL programming.
I have a query regarding vectors. If I am iterating over a vector
using a iterator, but do some operations that modify the size of the
vector. Will the iterator recognize this?
No.

A vector's iterators are invalidated when its memory is reallocated.
Additionally, inserting or deleting an element in the middle of a
vector invalidates all iterators that point to elements following the
insertion or deletion point. It follows that you can prevent a
vector's iterators from being invalidated if you use reserve() to
preallocate as much memory as the vector will ever use, and if all
insertions and deletions are at the vector's end.
<http://www.sgi.com/tech/stl/Vector.html>
I wrote the following program to test this out.
Try adding "a.reserve(5);" at any point after 'a' is defined, and before
the loop.
#include <fstream>
#include <iostream>
#include <string>
#include <vector>

using namespace std;

int main()
{
vector<inta;

a.push_back(1);
a.push_back(2);
a.push_back(3);
cout<<"Vector test begin"<<endl;
vector<int>::iterator iter0;
for(iter0=a.begin(); iter0!=a.end(); iter0++)
{
cout << "\n value: " << (*iter0)<<endl;
if(*iter0 == 2)
{
a.push_back(4);
a.push_back(5);
}
}
cout<<"Vector test end";
}
Jul 4 '08 #3
Thank you all for the replies. I used a loop variable and
vector.size() instead of the iterator to solve my problem.

On Jul 4, 6:31*pm, "Daniel T." <danie...@earthlink.netwrote:
prasadmpa...@gmail.com wrote:
I am new STL programming.
I have a query regarding vectors. If I am iterating over a vector
using a iterator, but do some operations that modify the size of the
vector. Will the iterator recognize this?

No.

* *A vector's iterators are invalidated when its memory is reallocated.
* *Additionally, inserting or deleting an element in the middle of a
* *vector invalidates all iterators that point to elements following the
* *insertion or deletion point. It follows that you can prevent a
* *vector's iterators from being invalidated if you use reserve() to
* *preallocate as much memory as the vector will ever use, and if all
* *insertions and deletions are at the vector's end.
* *<http://www.sgi.com/tech/stl/Vector.html>
I wrote the following program to test this out.

Try adding "a.reserve(5);" at any point after 'a' is defined, and before
the loop.
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main()
{
* *vector<inta;
* *a.push_back(1);
* *a.push_back(2);
* *a.push_back(3);
* *cout<<"Vector test begin"<<endl;
* *vector<int>::iterator iter0;
* *for(iter0=a.begin(); iter0!=a.end(); iter0++)
* *{
* * * * * *cout << "\n value: " << (*iter0)<<endl;
* * * * * *if(*iter0 == 2)
* * * * * *{
* * * * * * * * * *a.push_back(4);
* * * * * * * * * *a.push_back(5);
* * * * * *}
* *}
* *cout<<"Vector test end";
}

Jul 5 '08 #4
Jerry Coffin <jc*****@taeus.comwrote:
pr**********@gmail.com says...
I am new STL programming.
I have a query regarding vectors. If I am iterating over a vector
using a iterator, but do some operations that modify the size of the
vector. Will the iterator recognize this?

I wrote the following program to test this out.

#include <fstream>
#include <iostream>
#include <string>
#include <vector>

using namespace std;

int main()
{
vector<inta;

a.push_back(1);
a.push_back(2);
a.push_back(3);
cout<<"Vector test begin"<<endl;
vector<int>::iterator iter0;
for(iter0=a.begin(); iter0!=a.end(); iter0++)
{
cout << "\n value: " << (*iter0)<<endl;
if(*iter0 == 2)
{
a.push_back(4);
a.push_back(5);
}
}
cout<<"Vector test end";
}

A push_back on a vector invalidates all iterators into that vector.
Not quite true. push_back only invalidates the iterators if size() <
capacity() before the push_back occurs. If the OP had done a reserve(5)
before entering the loop, all would have been well.
Jul 5 '08 #5
In article <da****************************@earthlink.vsrv-
sjc.supernews.net>, da******@earthlink.net says...

[ ... ]
A push_back on a vector invalidates all iterators into that vector.

Not quite true. push_back only invalidates the iterators if size() <
capacity() before the push_back occurs. If the OP had done a reserve(5)
before entering the loop, all would have been well.
True -- better than 'reserve(5)' would have been something like:
a.reserve(a.size()+2)

I still think it's better to directly express what you're doing with an
algorithm though.

--
Later,
Jerry.

The universe is a figment of its own imagination.
Jul 5 '08 #6
Jerry Coffin <jc*****@taeus.comwrote:
I still think it's better to directly express what you're doing with an
algorithm though.
Agreed.
Jul 5 '08 #7
On Jul 5, 9:52*am, "Daniel T." <danie...@earthlink.netwrote:
Jerry Coffin <jcof...@taeus.comwrote:
I still think it's better to directly express what you're doing with an
algorithm though.

Agreed.
Thank you all for the suggestions.
What I am actually trying to do is generate a state space. I start
with a initial state and then based on rule matches generate
additional states. I continue doing this until no new states are
generated. I am storing these states in a vector. Is this a good idea?
Based on all the above replies there are multiple ways of doing this
namely

1. using vector.reserve()
2. using list
3. using a loop variable.

Which is the best way to implement this?

Jul 5 '08 #8
Prasad Patil <pr**********@gmail.comwrote:
On Jul 5, 9:52*am, "Daniel T." <danie...@earthlink.netwrote:
Jerry Coffin <jcof...@taeus.comwrote:
I still think it's better to directly express what you're doing with an
algorithm though.
Agreed.

Thank you all for the suggestions.
What I am actually trying to do is generate a state space. I start
with a initial state and then based on rule matches generate
additional states. I continue doing this until no new states are
generated. I am storing these states in a vector. Is this a good idea?
Based on all the above replies there are multiple ways of doing this
namely

1. using vector.reserve()
2. using list
3. using a loop variable.

Which is the best way to implement this?
Jerry pointed the way to the best solution. For any particular "state
space" there is a query, how many new states should be generated, and a
command, generate X states.

The loop you presented tried to both determine the number of new states
and generate them at the same time, and I think that is doing too much.
Better would be to have two separate functions, one that determines the
new states to generate, and another that actually does it.
Jul 5 '08 #9
On Jul 5, 6:31*pm, "Daniel T." <danie...@earthlink.netwrote:
Prasad Patil <prasadmpa...@gmail.comwrote:
On Jul 5, 9:52*am, "Daniel T." <danie...@earthlink.netwrote:
Jerry Coffin <jcof...@taeus.comwrote:
I still think it's better to directly express what you're doing with an
algorithm though.
Agreed.
Thank you all for the suggestions.
What I am actually trying to do is generate a state space. I start
with a initial state and then based on rule matches generate
additional states. I continue doing this until no new states are
generated. I am storing these states in a vector. Is this a good idea?
Based on all the above replies there are multiple ways of doing this
namely
1. using vector.reserve()
2. using list
3. using a loop variable.
Which is the best way to implement this?

Jerry pointed the way to the best solution. For any particular "state
space" there is a query, how many new states should be generated, and a
command, generate X states.

The loop you presented tried to both determine the number of new states
and generate them at the same time, and I think that is doing too much.
Better would be to have two separate functions, one that determines the
new states to generate, and another that actually does it.
Thanks Daniel and Jerry for the advice. I did implement the algorithm
the way you suggested.

I have another newbie question.
-----------------------------

class b{

public: b(int val)
{
var = val;
}
int var;

};

class a{
public:
a(vector<bvals)
{
objB= vals;
}

vector<bobjB;
};
int main()
{
vector<avec_of_a;

vector<btemp1;
temp1.push_back(b(1));
temp1.push_back(b(2));
temp1.push_back(b(3));

vector<btemp2;
temp2.push_back(b(1));
temp2.push_back(b(2));
temp2.push_back(b(3));

vec_of_a.push_back(a(temp1));
vec_of_a.push_back(a(temp2));

}

//If I need to add another element to temp2 after it has been pushed
to vec_of_a, how do I do it? because as I understand iterators don't
allow me to modify the elements of the vector.

Jul 7 '08 #10
In article <62d91254-dff3-4359-90f8-5da22195d8c6
@d45g2000hsc.googlegroups.com>, pr**********@gmail.com says...
On Jul 5, 6:31Â*pm, "Daniel T." <danie...@earthlink.netwrote:
Prasad Patil <prasadmpa...@gmail.comwrote:
On Jul 5, 9:52Â*am, "Daniel T." <danie...@earthlink.netwrote:
Jerry Coffin <jcof...@taeus.comwrote:
I still think it's better to directly express what you're doing with an
algorithm though.
Agreed.
Thank you all for the suggestions.
What I am actually trying to do is generate a state space. I start
with a initial state and then based on rule matches generate
additional states. I continue doing this until no new states are
generated. I am storing these states in a vector. Is this a good idea?
Based on all the above replies there are multiple ways of doing this
namely
1. using vector.reserve()
2. using list
3. using a loop variable.
Which is the best way to implement this?
Jerry pointed the way to the best solution. For any particular "state
space" there is a query, how many new states should be generated, and a
command, generate X states.

The loop you presented tried to both determine the number of new states
and generate them at the same time, and I think that is doing too much.
Better would be to have two separate functions, one that determines the
new states to generate, and another that actually does it.
Thanks Daniel and Jerry for the advice. I did implement the algorithm
the way you suggested.

I have another newbie question.
-----------------------------

class b{

public: b(int val)
{
var = val;
}
int var;

};

class a{
public:
a(vector<bvals)
{
objB= vals;
}

vector<bobjB;
};
int main()
{
vector<avec_of_a;

vector<btemp1;
temp1.push_back(b(1));
temp1.push_back(b(2));
temp1.push_back(b(3));

vector<btemp2;
temp2.push_back(b(1));
temp2.push_back(b(2));
temp2.push_back(b(3));

vec_of_a.push_back(a(temp1));
vec_of_a.push_back(a(temp2));

}

//If I need to add another element to temp2 after it has been pushed
to vec_of_a, how do I do it? because as I understand iterators don't
allow me to modify the elements of the vector.
Yes and no. Iterators allow you to modify the individual elements --
i.e. an iterator gives you access to an element, and you can modify that
element by writing to it.

A normal iterator does NOT give you access to the container that holds
the element. If you want to add an item to the container, you need some
access to the container, such as using the container's push_back member,
or creating some sort of insert iterator for the container (e.g.
insert_iterator, back_insert_iterator, etc.)

As you've defined things right now, the objB member of class a is
public, so you can do something like this:

vec_of_a.push_back(a(temp2));

// add element to vec_of_a[0]
vec_of_a[0].objB.push_back(b(4));

That's probably not a good idea though -- generally speaking, a class
shouldn't give direct access to its internal data. If you want class a
to act like a vector, you could provide a vector-like interface to do
so.

class a {
vector<bobjB;
public:
a(vector<Bconst &vals) : objB(vals) {}

void push_back(b newB) { objB.push_back(newB); }
};

Note that passing a vector by value is (at least potentially) quite
expensive, so for this situation I've passed it by reference (to const)
instead.

Also note that since the ctors for neither a nor b is explicit, all the
conversions can be done implicitly:

int main() {
vector<avec_of_a;
vector<btemp1;

temp1.push_back(1);
temp1.push_back(2);
temp1.push_back(3);

vector<btemp2;
temp2.push_back(1);
temp2.push_back(2);
temp2.push_back(3);

vec_of_a.push_back(temp1);
vec_of_a.push_back(temp2);

return 0;
}

Of course it may be open to question whether 1) the explicit cases are
clearer, and/or 2) you might want to make the ctors explicit, so these
conversions won't happen by accident.

--
Later,
Jerry.

The universe is a figment of its own imagination.
Jul 7 '08 #11
Prasad Patil <pr**********@gmail.comwrote:
Thanks Daniel and Jerry for the advice. I did implement the algorithm
the way you suggested.

I have another newbie question.
-----------------------------

class b{

public: b(int val)
{
var = val;
}
int var;

};

class a{
public:
a(vector<bvals)
{
objB= vals;
}

vector<bobjB;
};
int main()
{
vector<avec_of_a;

vector<btemp1;
temp1.push_back(b(1));
temp1.push_back(b(2));
temp1.push_back(b(3));

vector<btemp2;
temp2.push_back(b(1));
temp2.push_back(b(2));
temp2.push_back(b(3));

vec_of_a.push_back(a(temp1));
vec_of_a.push_back(a(temp2));

}

If I need to add another element to temp2 after it has been pushed
to vec_of_a, how do I do it?
First, temp2 has not been pushed into vec_of_a. A *copy* of temp2 has
been made by the object vec_of_a[1].

I suspect that what you are really asking is how to add a 'b' to the 'a'
object that occupies that position in vec_of_a. The answer is that you
provide a member-function in 'a' that lets you do it.

class a {
vector<bobjB;
public:
a( const vector<b>& vals ): objB( vals ) { }

void push_back( const B& b ) {
objB.push_back( b );
}
};

in main:

vec_of_a[0].push_back( b(5) );
because as I understand iterators don't allow me to modify the
elements of the vector.
Iterators allow you to modify the elements in the vector, they *don't*
allow you to modify the vector itself. Understanding this distinction
will go a long way toward understanding iterators.
Jul 7 '08 #12
Thanks Dan and Jerry for the replies :) Really appreciate the help .
I was able to implement the state space and this how I did it..
Slightly different from what you guys suggested, but works for me.

currentPosition = 0;
do{

1. Get state at currentPosition in the state_space_vector
2. Generate states based on transition rules and store them
in a temporary_vector.
3. Insert newly generated states from temporary vector into
state_space_vector after checking if they already exist in the
state_space_vector.
4. Increment the curentPosition.
} while(currentPosition < state_space_vector.size());

A final newbie question. Can you point me to some resources regarding
copy constructor, return using reference/copy. I regularly get
confused by these. (I am mainly a java programmer so everything is
return by reference which is not always the case in c++).

On Jul 7, 6:56*am, "Daniel T." <danie...@earthlink.netwrote:
Prasad Patil <prasadmpa...@gmail.comwrote:
Thanks Daniel and Jerry for the advice. I did implement the algorithm
the way you suggested.
I have another newbie question.
-----------------------------
class b{
public: * b(int val)
*{
* * var = val;
*}
*int var;
};
class a{
*public:
* * a(vector<bvals)
*{
* * objB= vals;
*}
* * vector<bobjB;
};
int main()
{
*vector<avec_of_a;
*vector<btemp1;
*temp1.push_back(b(1));
*temp1.push_back(b(2));
*temp1.push_back(b(3));
*vector<btemp2;
*temp2.push_back(b(1));
*temp2.push_back(b(2));
*temp2.push_back(b(3));
*vec_of_a.push_back(a(temp1));
*vec_of_a.push_back(a(temp2));
}
If I need to add another element to temp2 after it has been pushed
to vec_of_a, how do I do it?

First, temp2 has not been pushed into vec_of_a. A *copy* of temp2 has
been made by the object vec_of_a[1].

I suspect that what you are really asking is how to add a 'b' to the 'a'
object that occupies that position in vec_of_a. The answer is that you
provide a member-function in 'a' that lets you do it.

class a {
* *vector<bobjB;
public:
* *a( const vector<b>& vals ): objB( vals ) { }

* *void push_back( const B& b ) {
* * * objB.push_back( b );
* *}

};

in main:

vec_of_a[0].push_back( b(5) );
because as I understand iterators don't allow me to modify the
elements of the vector.

Iterators allow you to modify the elements in the vector, they *don't*
allow you to modify the vector itself. Understanding this distinction
will go a long way toward understanding iterators.
Jul 11 '08 #13
Prasad Patil <pr**********@gmail.comwrote:
A final newbie question. Can you point me to some resources regarding
copy constructor, return using reference/copy.
The copy constructor "Type(const Type&);" doesn't return anything.
Jul 11 '08 #14

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

Similar topics

3
by: Alexander Stippler | last post by:
Hi, I have to design some two dimensional iterators and I'm not quite sure about the design. I'd like to have the iterators mostly STL-like. The STL does not contain two dimensional iterators, I...
3
by: codefixer | last post by:
Hello, I am trying to understand if ITERATORS are tied to CONTAINERS. I know the difference between 5 different or 6(Trivial, on SGI). But what I fail to understand is how can I declare all 5...
4
by: fastback66 | last post by:
Evidently per the C++ standard, it is not possible to measure the distance between two stream iterators, because two non-end-of-stream iterators are equal when they are constructed from the same...
2
by: agenevera | last post by:
I am trying to insert a vector into a larger vector at various positions. This, however, will not compile. vector<double>::iterator pos; vector<double> tmp; vector<double> m_parameters;...
2
by: ma740988 | last post by:
typedef std::vector < std::complex < double > > complex_vec_type; // option1 int main() { complex_vec_type cc ( 24000 ); complex_vec_type dd ( &cc, &cc ); } versus
8
by: desktop | last post by:
In accelerated C++ on page 146 there is this example: template <class In, class Out> Out copy(In begin, In end, Out dest) { While (begin != end) *dest++ = *begin++; return dest; }
7
by: desktop | last post by:
I am not sure I quite understand the use of iterators. I have this int array: int a = {1,2,3,4,5} I would now like to make an iterator to the first and last element: std::iterator<intiter;...
18
by: desktop | last post by:
1) I have this code: std::list<intmylist; mylist.push_back(1); mylist.push_back(2); mylist.push_back(3); mylist.push_back(4);
0
by: subramanian100in | last post by:
Suppose I have vector<intc; for (int i = 0; i < 10; ++i) c.push_back(i); vector<int>::iterator it = find(c.begin(), c.end(), 5); If I do, c.insert(c.begin(), 10);
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: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
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
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

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.