Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > vector assign() trouble

Reply
Thread Tools

vector assign() trouble

 
 
nandor.sieben@gmail.com
Guest
Posts: n/a
 
      01-08-2007
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?

 
Reply With Quote
 
 
 
 
nandor.sieben@gmail.com
Guest
Posts: n/a
 
      01-08-2007
forgot the definition of

#define BE(v) v.begin(), v.end()

 
Reply With Quote
 
 
 
 
Victor Bazarov
Guest
Posts: n/a
 
      01-09-2007
http://www.velocityreviews.com/forums/(E-Mail Removed) wrote:
> 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
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask


 
Reply With Quote
 
peter koch
Guest
Posts: n/a
 
      01-09-2007

(E-Mail 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

 
Reply With Quote
 
Victor Bazarov
Guest
Posts: n/a
 
      01-09-2007
peter koch wrote:
> (E-Mail 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.


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
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask


 
Reply With Quote
 
Volker Wippel
Guest
Posts: n/a
 
      01-09-2007
Victor Bazarov wrote:
> (E-Mail Removed) wrote:
>> 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);
 
Reply With Quote
 
Sylvester Hesp
Guest
Posts: n/a
 
      01-09-2007
"peter koch" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed) ps.com...
>
> 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


 
Reply With Quote
 
Sylvester Hesp
Guest
Posts: n/a
 
      01-09-2007
"Sylvester Hesp" <(E-Mail Removed)> wrote in message
news:45a39395$0$322$(E-Mail Removed)4all.nl...
> namelijk


I'm sorry my Dutch became intertwined with the words. I meant "namely"


 
Reply With Quote
 
Roland Pibinger
Guest
Posts: n/a
 
      01-09-2007
On Mon, 8 Jan 2007 20:10:54 -0500, "Victor Bazarov" wrote:
>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
 
Reply With Quote
 
Victor Bazarov
Guest
Posts: n/a
 
      01-09-2007
Volker Wippel wrote:
> Victor Bazarov wrote:
>> (E-Mail Removed) wrote:
>>> 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
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
const vector<A> vs vector<const A> vs const vector<const A> Javier C++ 2 09-04-2007 08:46 PM
Initializing vector<vector<int> > and other vector questions... pmatos C++ 6 04-26-2007 05:39 PM
Free memory allocate by a STL vector, vector of vector, map of vector Allerdyce.John@gmail.com C++ 8 02-18-2006 12:48 AM
how the vector is created, how to pass vector to webservices method apachesoap:Vector Rushikesh Joshi Perl Misc 0 07-10-2004 01:04 PM
how do i create a vector within a vector ? learningjava Java 5 10-17-2003 10:19 PM



Advertisments