473,756 Members | 5,656 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

changing vector while processing one of its elements?

Hi,

I observed a behavior that I didn't expect: I have a vector of sets. I
iterate over the first of these sets, and while I iterate over it, I
add another set at the end of the vector. I thought that shouldn't
affect the first set I am iterating over, but it does, and I get a
segmentation fault.

See the example program below.

It works fine if I make set0 a *copy* of v[0], instead of a reference
or a pointer, but I would rather not copy it (this routine is called
very often in my program and I don't see why I should make an
expensive copy).

How can I fix this? Thanks!

int main(int argc, char** argv){
std::vector<std ::set<int v;
std::set<ints;
s.insert(1);
s.insert(2);
v.push_back(s);
std::set<int>& set0 = v[0]; // using reference because we don't want
to copy to local var (too expensive)
for(std::set<in t>::const_itera tor it = set0.begin(); it !=
set0.end(); ++it){
std::cout << *it << std::endl;
std::set<inttmp ;
tmp.insert(10);
v.push_back(tmp ); // will be v[1], so it shouldn't change set0 or
its
iterator?
}
return 0;
}

As output I get:
1
10
1
10
1
10
....
Segmentation fault
Jun 27 '08 #1
3 1481
Markus Dehmann wrote:
Hi,

I observed a behavior that I didn't expect: I have a vector of sets. I
iterate over the first of these sets, and while I iterate over it, I
add another set at the end of the vector. I thought that shouldn't
affect the first set I am iterating over, but it does, and I get a
segmentation fault.
It does not affect the first set _as a value_. However, it affects the first
set _as an object (region of memory)_ because inserting an element into the
vector can trigger a re-allocation of the vector and then all current
elements are moved around.
>
See the example program below.

It works fine if I make set0 a *copy* of v[0], instead of a reference
or a pointer, but I would rather not copy it (this routine is called
very often in my program and I don't see why I should make an
expensive copy).

How can I fix this? Thanks!

int main(int argc, char** argv){
std::vector<std ::set<int v;
std::set<ints;
s.insert(1);
s.insert(2);
v.push_back(s);
std::set<int>& set0 = v[0]; // using reference because we don't want
to copy to local var (too expensive)
You are using a reference. Insertions into a vector can invalidate all
references, pointers, and iterators into the vector (for the reasons
mentioned above).
for(std::set<in t>::const_itera tor it = set0.begin(); it !=
set0.end(); ++it){
std::cout << *it << std::endl;
std::set<inttmp ;
tmp.insert(10);
v.push_back(tmp ); // will be v[1], so it shouldn't change set0 or
its
iterator?
}
return 0;
}

As output I get:
1
10
1
10
1
10
...
Segmentation fault
Yup, that the undefined behavior from using an invalidated reference.
Your options include:

a) Use std::list instead of std::vector.
b) Instead of inserting the new sets right away, put them on hold.
c) Use std::vector< some_smart_poin ter< std::set<int >.
Best

Kai-Uwe Bux
Jun 27 '08 #2
On 9 Jun, 23:43, Kai-Uwe Bux <jkherci...@gmx .netwrote:
Markus Dehmann wrote:
Hi,
I observed a behavior that I didn't expect: I have a vector of sets. I
iterate over the first of these sets, and while I iterate over it, I
add another set at the end of the vector. I thought that shouldn't
affect the first set I am iterating over, but it does, and I get a
segmentation fault.
[snip]
Your options include:

a) Use std::list instead of std::vector.
b) Instead of inserting the new sets right away, put them on hold.
c) Use std::vector< some_smart_poin ter< std::set<int >.
Depending on your program, you may get away with
d) If possible, use the reserve() member function of vector to ensure
that no reallocation takes place.

Like this:

std::vector<std ::set<int v;
v.reserve(10) // If you know beforehand that no more than 10
elements will be inserted.

Note that you can also check size() vs. capacity() to determine
whether a push_back() will trigger a reallocation (invalidating all
references)

DP
Jun 27 '08 #3
On Jun 9, 11:43 pm, Kai-Uwe Bux <jkherci...@gmx .netwrote:
Markus Dehmann wrote:
I observed a behavior that I didn't expect: I have a vector
of sets. I iterate over the first of these sets, and while I
iterate over it, I add another set at the end of the vector.
I thought that shouldn't affect the first set I am iterating
over, but it does, and I get a segmentation fault.
It does not affect the first set _as a value_. However, it
affects the first set _as an object (region of memory)_
because inserting an element into the vector can trigger a
re-allocation of the vector and then all current elements are
moved around.
See the example program below.
It works fine if I make set0 a *copy* of v[0], instead of a reference
or a pointer, but I would rather not copy it (this routine is called
very often in my program and I don't see why I should make an
expensive copy).
How can I fix this? Thanks!
int main(int argc, char** argv){
std::vector<std ::set<int v;
std::set<ints;
s.insert(1);
s.insert(2);
v.push_back(s);
std::set<int>& set0 = v[0]; // using reference because we don't want
to copy to local var (too expensive)
You are using a reference. Insertions into a vector can
invalidate all references, pointers, and iterators into the
vector (for the reasons mentioned above).
for(std::set<in t>::const_itera tor it = set0.begin(); it !=
set0.end(); ++it){
std::cout << *it << std::endl;
std::set<inttmp ;
tmp.insert(10);
v.push_back(tmp ); // will be v[1], so it shouldn't change set0 or
its
iterator?
}
return 0;
}
As output I get:
1
10
1
10
1
10
...
Segmentation fault
Yup, that the undefined behavior from using an invalidated reference.
Your options include:
a) Use std::list instead of std::vector.
b) Instead of inserting the new sets right away, put them on hold.
c) Use std::vector< some_smart_poin ter< std::set<int >.
d) Use v[0] each time you need it, rather than saving the
reference.

--
James Kanze (GABI Software) email:ja******* **@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientier ter Datenverarbeitu ng
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Jun 27 '08 #4

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

Similar topics

2
4432
by: Justin | last post by:
Hi! i'm a beginner user of c++ and i need some help. I use visual c++ 6.0 on a p4 under windows 2000. First, i read a text file with 3 fields: gestionnal age (GA), birth weight (BW) and repetition (the number fo patient for specific GA and BW). The file is ordered by GA and BW. I put each field in an vector. GA took value between 22 and 44 and i want to create 2 others vector (qcount, qcumulative) containing the number of patients for...
4
4326
by: Matt Garman | last post by:
Is there any difference, performance-wise, accessing elements of a vector using iterators or the subscript operator? In other words, say I have a vector of strings: vector<string> strvec; After some processing, the vector has a very large (>50,000) number of elements. Is there any performance difference in the following methods of vector access?
9
3182
by: fudmore | last post by:
Hello Everybody. I have a Segmentation fault problem. The code section at the bottom keeps throwing a Segmentation fault when it enters the IF block for the second time. const int WORDS_PER_LINE = 4; when counter == 7 is when the string Concatenation fails within the IF block.
34
4174
by: Adam Hartshorne | last post by:
Hi All, I have the following problem, and I would be extremely grateful if somebody would be kind enough to suggest an efficient solution to it. I create an instance of a Class A, and "push_back" a copy of this into a vector V. This is repeated many times in an iterative process. Ok whenever I "push_back" a copy of Class A, I also want to assign a pointer contained in an exisiting instance of a Class B to this
10
4839
by: Bob | last post by:
Here's what I have: void miniVector<T>::insertOrder(miniVector<T>& v,const T& item) { int i, j; T target; vSize += 1; T newVector; newVector=new T;
12
6729
by: Piotr | last post by:
In effective STL, it said one should not use vector<bool> but use dequeue<bool> instead. But can dequeue<bool> has random access iterator? and I do this? dequeue<bool> myboolarray; if (myboolarray) { // do this... } if not, is there another solution?
7
3010
by: Dilip | last post by:
If you reserve a certain amount of memory for a std::vector, what happens when a reallocation is necessary because I overshot the limit? I mean, say I reserve for 500 elements, the insertion of 501st element is going to cause some more allocation -- for arguments sake if the vector re-grows to accomodate 1000 elements, I play around with it and completely erase everything in it after I am done. Now how much does the vector hold? Do I...
9
3759
by: Jess | last post by:
Hello, I tried to clear a vector "v" using "v.clear()". If "v" contains those objects that are non-built-in (e.g. string), then "clear()" can indeed remove all contents. However, if "v" contains built-in types (e.g. int), then "clear()" doesn't remove anything at all. Why does "clear()" have this behaviour? Also, when I copy one vector "v1" from another vector "v2", with "v1" longer than "v2" (e.g. "v1" has 2 elements and "v2" has...
19
4896
by: Matteo Migliore | last post by:
Hi! I've to scale a vector of numbers of size N to a vector of size M. The trasformation is like a zoom on images but I need on a vector. The second size can be M >= N or M <= N, M 0. The value for each element can be from 0 to 255. Is there some methods that can I use?
0
9454
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, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9271
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 effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10028
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, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
9707
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 protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
1
7242
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 presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6533
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5139
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
3804
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
3
2664
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.