vector assign() trouble

N

nandor.sieben

I am trying to replace

template < class T > void
set2vector (const set < T > &s, vector < T > &v)
{
typename set < T >::iterator it;
for (it = s.begin (); it != s.end (); it++) {
v.push_back (*it);
}
}

with

template < class T > void
set2vector (const set < T > &s, vector < T > &v)
{
v.assign(BE(s));
}

but I get a segmentation fault. I am using g++ on Fedora core 4. Aren't
these code segments equivalent?
 
V

Victor Bazarov

I am trying to replace

template < class T > void
set2vector (const set < T > &s, vector < T > &v)
{
typename set < T >::iterator it;
for (it = s.begin (); it != s.end (); it++) {
v.push_back (*it);
}
}

with

template < class T > void
set2vector (const set < T > &s, vector < T > &v)
{
v.assign(BE(s));
}

but I get a segmentation fault. I am using g++ on Fedora core 4.
Aren't these code segments equivalent?

Of course not. If the vector is empty, pushing back into it fills
it with those elements. Assigning does not introduce new elements
into the vector, but instead changes the values of the existing
ones. The latter variant is actually equivalent to

{ size_t i = 0;
for (it = s.begin(); it != s.end(); ++it)
v[i++] = *it;
}

You need to precede your call to 'assign' with 'resize':

v.resize(s.size());
v.assign(BE(s));

V
 
P

peter koch

(e-mail address removed) skrev:
I am trying to replace

template < class T > void
set2vector (const set < T > &s, vector < T > &v)
{
typename set < T >::iterator it;
for (it = s.begin (); it != s.end (); it++) {
v.push_back (*it);
}
}

with

template < class T > void
set2vector (const set < T > &s, vector < T > &v)
{
v.assign(BE(s));
}

but I get a segmentation fault. I am using g++ on Fedora core 4. Aren't
these code segments equivalent?

As Victor already pointed out, assign assigns and does not create new
elements. But I do not see the need for the function in the first
place: why not simply write
std::vector<T> v(s.begin(),s.end());

? This will almost certainly be optimal code.

/Peter
 
V

Victor Bazarov

peter said:
(e-mail address removed) skrev:

As Victor already pointed out, assign assigns and does not create new
elements. But I do not see the need for the function in the first
place: why not simply write
std::vector<T> v(s.begin(),s.end());

? This will almost certainly be optimal code.

I would guess that the function is for repeated use with already
created vector (no need to reconstruct it). The following does the
same thing

existingvector.swap(std::vector(s.begin(), s.end()));

but less readable than

set2vector(s, existingvector);

(arguably).

V
 
V

Volker Wippel

Victor said:
I am trying to replace

template < class T > void
set2vector (const set < T > &s, vector < T > &v)
{
typename set < T >::iterator it;
for (it = s.begin (); it != s.end (); it++) {
v.push_back (*it);
}
}

with

template < class T > void
set2vector (const set < T > &s, vector < T > &v)
{
v.assign(BE(s));
}

but I get a segmentation fault. I am using g++ on Fedora core 4.
Aren't these code segments equivalent?

Of course not. If the vector is empty, pushing back into it fills
it with those elements. Assigning does not introduce new elements
into the vector, but instead changes the values of the existing
ones. The latter variant is actually equivalent to

{ size_t i = 0;
for (it = s.begin(); it != s.end(); ++it)
v[i++] = *it;
}

You need to precede your call to 'assign' with 'resize':

v.resize(s.size());
v.assign(BE(s));

V

I am confused. I found in 23.2.4.1

template<class InputIterator>
void assign(InputIterator _First, InputIterator _Last);

Effects:

erase(begin(), end());
insert(begin(), first, last);
 
S

Sylvester Hesp

peter koch said:
As Victor already pointed out, assign assigns and does not create new
elements.

I'm sorry but that's just nonsense. The assign function does the same as
it's corresponding constructor in vector, namelijk reconstructing the vector
with the range of elements you've provided. And as the OP already pointed
out, the standard clearly says so:

template<class InputIterator>
void assign(InputIterator _First, InputIterator _Last);

Effects:

erase(begin(), end());
insert(begin(), first, last);


Of course this still doesn't make the two functions equivalent: the first
pushes all the elements to the end of the vector - it doesn't clear it
first. I think the segfault is caused by something else that just happened
to be triggered by the minor change in code. If both the set and the vector
are valid, v.assign(s.begin(), s.end()) won't segfault on you unless either
your T is conceptually flawed or your heap is corrupted (generally speaking
of course, there could be tons of other totally unrelated issues).

- Sylvester
 
R

Roland Pibinger

I would guess that the function is for repeated use with already
created vector (no need to reconstruct it). The following does the
same thing

existingvector.swap(std::vector(s.begin(), s.end()));

You cannot use a temporary with vector::swap().

Best wishes,
Roland Pibinger
 
V

Victor Bazarov

Volker said:
Victor said:
I am trying to replace

template < class T > void
set2vector (const set < T > &s, vector < T > &v)
{
typename set < T >::iterator it;
for (it = s.begin (); it != s.end (); it++) {
v.push_back (*it);
}
}

with

template < class T > void
set2vector (const set < T > &s, vector < T > &v)
{
v.assign(BE(s));
}

but I get a segmentation fault. I am using g++ on Fedora core 4.
Aren't these code segments equivalent?

Of course not. If the vector is empty, pushing back into it fills
it with those elements. Assigning does not introduce new elements
into the vector, but instead changes the values of the existing
ones. The latter variant is actually equivalent to

{ size_t i = 0;
for (it = s.begin(); it != s.end(); ++it)
v[i++] = *it;
}

You need to precede your call to 'assign' with 'resize':

v.resize(s.size());
v.assign(BE(s));

V

I am confused. I found in 23.2.4.1

template<class InputIterator>
void assign(InputIterator _First, InputIterator _Last);

Effects:

erase(begin(), end());
insert(begin(), first, last);

You're right. I messed up. In my defence I didn't have the code
to work with. See FAQ 5.8.

V
 
V

Victor Bazarov

Roland said:
You cannot use a temporary with vector::swap().

Right. It ought to be the other way around:

std::vector(s.begin(), s.end()).swap(existingvector);

V
 
P

peter koch

Sylvester Hesp skrev:
I'm sorry but that's just nonsense. The assign function does the same as
it's corresponding constructor in vector, namelijk reconstructing the vector
with the range of elements you've provided.
[snip]

Right. One of the (few) times that Victor was wrong and my appeal to
authority became to strong;-)

/Peter
 

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,755
Messages
2,569,536
Members
45,020
Latest member
GenesisGai

Latest Threads

Top