vector assign() trouble

Discussion in 'C++' started by nandor.sieben@gmail.com, Jan 8, 2007.

  1. Guest

    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?
     
    , Jan 8, 2007
    #1
    1. Advertising

  2. Guest

    forgot the definition of

    #define BE(v) v.begin(), v.end()
     
    , Jan 8, 2007
    #2
    1. Advertising

  3. 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
     
    Victor Bazarov, Jan 9, 2007
    #3
  4. peter koch Guest

    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
     
    peter koch, Jan 9, 2007
    #4
  5. peter koch wrote:
    > 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
     
    Victor Bazarov, Jan 9, 2007
    #5
  6. Victor Bazarov wrote:
    > 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);
     
    Volker Wippel, Jan 9, 2007
    #6
  7. "peter koch" <> wrote in message
    news:...
    >
    > 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, Jan 9, 2007
    #7
  8. "Sylvester Hesp" <> wrote in message
    news:45a39395$0$322$4all.nl...
    > namelijk


    I'm sorry my Dutch became intertwined with the words. I meant "namely" ;)
     
    Sylvester Hesp, Jan 9, 2007
    #8
  9. 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
     
    Roland Pibinger, Jan 9, 2007
    #9
  10. Volker Wippel wrote:
    > Victor Bazarov wrote:
    >> 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
     
    Victor Bazarov, Jan 9, 2007
    #10
  11. Roland Pibinger wrote:
    > 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().


    Right. It ought to be the other way around:

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

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Jan 9, 2007
    #11
  12. peter koch Guest

    Sylvester Hesp skrev:
    > "peter koch" <> wrote in message
    > news:...
    > >
    > > 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.

    [snip]

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

    /Peter
     
    peter koch, Jan 13, 2007
    #12
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. pmatos
    Replies:
    6
    Views:
    24,125
  2. Replies:
    8
    Views:
    1,999
    Csaba
    Feb 18, 2006
  3. Chris Roth

    Vector Assign vs Vector operator=

    Chris Roth, Feb 21, 2007, in forum: C++
    Replies:
    4
    Views:
    392
    Ron Natalie
    Feb 22, 2007
  4. Javier
    Replies:
    2
    Views:
    622
    James Kanze
    Sep 4, 2007
  5. Rushikesh Joshi
    Replies:
    0
    Views:
    397
    Rushikesh Joshi
    Jul 10, 2004
Loading...

Share This Page