Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C++ (http://www.velocityreviews.com/forums/f39-c.html)
-   -   vector assign() trouble (http://www.velocityreviews.com/forums/t459730-vector-assign-trouble.html)

nandor.sieben@gmail.com 01-08-2007 11:40 PM

vector assign() trouble
 
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?


nandor.sieben@gmail.com 01-08-2007 11:43 PM

Re: vector assign() trouble
 
forgot the definition of

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


Victor Bazarov 01-09-2007 12:31 AM

Re: vector assign() trouble
 
nandor.sieben@gmail.com 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



peter koch 01-09-2007 12:37 AM

Re: vector assign() trouble
 

nandor.sieben@gmail.com 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


Victor Bazarov 01-09-2007 01:10 AM

Re: vector assign() trouble
 
peter koch wrote:
> nandor.sieben@gmail.com 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



Volker Wippel 01-09-2007 08:44 AM

Re: vector assign() trouble
 
Victor Bazarov wrote:
> nandor.sieben@gmail.com 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);

Sylvester Hesp 01-09-2007 01:06 PM

Re: vector assign() trouble
 
"peter koch" <peter.koch.larsen@gmail.com> wrote in message
news:1168303060.747842.70220@11g2000cwr.googlegrou 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



Sylvester Hesp 01-09-2007 01:09 PM

Re: vector assign() trouble
 
"Sylvester Hesp" <s.hesp@oisyn.nl> wrote in message
news:45a39395$0$322$e4fe514c@news.xs4all.nl...
> namelijk


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



Roland Pibinger 01-09-2007 01:26 PM

Re: vector assign() trouble
 
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

Victor Bazarov 01-09-2007 02:25 PM

Re: vector assign() trouble
 
Volker Wippel wrote:
> Victor Bazarov wrote:
>> nandor.sieben@gmail.com 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




All times are GMT. The time now is 01:40 PM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.