vector push_back question

Discussion in 'C++' started by ma740988, Jan 8, 2006.

  1. ma740988

    ma740988 Guest

    Consider the source snippet

    int main()
    {
    std::vector<double> vec_push( 0x10 );
    size_t const SZ = vec_push.size();
    std::cout << vec_push.size() << std::endl;

    if ( SZ != 0x10 ) {
    cout << " something's amiss " << endl;
    return 0;
    }

    vec_push.reserve(0x10000); // for test ..
    for (size_t jdx(0); jdx < SZ; ++jdx)
    {
    vec_push.push_back( jdx );
    std::cout << " JDX " << jdx << std::endl;
    std::cout << " vec_push.size() " << vec_push.size() <<
    std::endl;
    }
    std::cout << vec_push.size() << std::endl;
    }

    ------ The results:
    16
    JDX 0
    vec_push.size() 17
    JDX 1
    vec_push.size() 18
    JDX 2
    vec_push.size() 19
    JDX 3
    vec_push.size() 20
    JDX 4
    vec_push.size() 21
    JDX 5
    vec_push.size() 22
    JDX 6
    vec_push.size() 23
    JDX 7
    vec_push.size() 24
    JDX 8
    vec_push.size() 25
    JDX 9
    vec_push.size() 26
    JDX 10
    vec_push.size() 27
    JDX 11
    vec_push.size() 28
    JDX 12
    vec_push.size() 29
    JDX 13
    vec_push.size() 30
    JDX 14
    vec_push.size() 31
    JDX 15
    vec_push.size() 32
    32
    -------
    At issue: The results from the program suggest that - with each call
    to push_back the vector re-allocates. A bit of a mystery since I've
    already allocated enough space with reserve

    This compiler ( which unfortunately I'm stuck with ) is gcc 2.96 -
    which I suspect is sub par. The question then becomes: From the looks
    of it, I suspect what it amounts to is - the implementation 'is what it
    is' and my choice the becomes a different container - perhaps or use
    operator []?

    i.e.
    vec_push[ jdx ] = jdx;

    In that regard, the result now becomes:

    16
    JDX 0
    vec_push.size() 16
    JDX 1
    vec_push.size() 16
    JDX 2
    vec_push.size() 16
    JDX 3
    vec_push.size() 16
    JDX 4
    vec_push.size() 16
    JDX 5
    vec_push.size() 16
    JDX 6
    vec_push.size() 16
    JDX 7
    vec_push.size() 16
    JDX 8
    vec_push.size() 16
    JDX 9
    vec_push.size() 16
    JDX 10
    vec_push.size() 16
    JDX 11
    vec_push.size() 16
    JDX 12
    vec_push.size() 16
    JDX 13
    vec_push.size() 16
    JDX 14
    vec_push.size() 16
    JDX 15
    vec_push.size() 16
    16
     
    ma740988, Jan 8, 2006
    #1
    1. Advertising

  2. ma740988

    Zara Guest

    On 8 Jan 2006 06:43:47 -0800, "ma740988" <> wrote:

    >Consider the source snippet
    >
    >int main()
    >{
    > std::vector<double> vec_push( 0x10 );
    > size_t const SZ = vec_push.size();
    > std::cout << vec_push.size() << std::endl;
    >
    > if ( SZ != 0x10 ) {
    > cout << " something's amiss " << endl;
    > return 0;
    > }
    >
    > vec_push.reserve(0x10000); // for test ..
    > for (size_t jdx(0); jdx < SZ; ++jdx)
    > {
    > vec_push.push_back( jdx );
    > std::cout << " JDX " << jdx << std::endl;
    > std::cout << " vec_push.size() " << vec_push.size() <<
    >std::endl;
    > }
    > std::cout << vec_push.size() << std::endl;
    >}
    >

    <snip>


    Size and capacity are not the same. Capacity is the actual number of
    objects available before another resize is necessary, while size is
    the actual number of objects already assigned.

    Look at it it this other way, and compare results:

    >int main()
    >{
    > std::vector<double> vec_push( 0x10 );
    > size_t const SZ = vec_push.size();
    > std::cout << vec_push.size() << std::endl;
    >
    > if ( SZ != 0x10 ) {
    > cout << " something's amiss " << endl;
    > return 0;
    > }
    >
    > vec_push.reserve(0x10000); // for test ..
    > for (size_t jdx(0); jdx < SZ; ++jdx)
    > {
    > vec_push.push_back( jdx );
    > std::cout << " JDX " << jdx << std::endl;
    > std::cout << " vec_push.size() " << vec_push.size() <<
    >std::endl;

    /* added */
    std::cout << " vec_push.capacity() " << vec_push.capacity() <<
    std::endl;
    /* end of additions */
    > }
    > std::cout << vec_push.size() << std::endl;
    >}
     
    Zara, Jan 9, 2006
    #2
    1. Advertising

  3. ma740988

    Heinz Ozwirk Guest

    "ma740988" <> schrieb im Newsbeitrag
    news:...
    > Consider the source snippet
    >
    > int main()
    > {
    > std::vector<double> vec_push( 0x10 );
    > size_t const SZ = vec_push.size();
    > std::cout << vec_push.size() << std::endl;
    >
    > if ( SZ != 0x10 ) {
    > cout << " something's amiss " << endl;
    > return 0;
    > }
    >
    > vec_push.reserve(0x10000); // for test ..
    > for (size_t jdx(0); jdx < SZ; ++jdx)
    > {
    > vec_push.push_back( jdx );
    > std::cout << " JDX " << jdx << std::endl;
    > std::cout << " vec_push.size() " << vec_push.size() <<
    > std::endl;
    > }
    > std::cout << vec_push.size() << std::endl;
    > }
    >
    > ------ The results:
    > 16
    > JDX 0
    > vec_push.size() 17

    ....
    > -------
    > At issue: The results from the program suggest that - with each call
    > to push_back the vector re-allocates. A bit of a mystery since I've
    > already allocated enough space with reserve


    This question suggest that you didn't read the docs properly. size returns
    the number of elements ACTUALLY USED while reserve allocates space for
    elements that CAN BE USED. If you want to know how muc memory has been
    reserved for a vector, you should use its capacity function. And you should
    also keep in mind that those constructors of std::vector, that require an
    element count, create vectors with the specified number of elements, not
    just with enough space for them.

    > This compiler ( which unfortunately I'm stuck with ) is gcc 2.96 -
    > which I suspect is sub par. The question then becomes: From the looks
    > of it, I suspect what it amounts to is - the implementation 'is what it
    > is' and my choice the becomes a different container - perhaps or use
    > operator []?
    >
    > i.e.
    > vec_push[ jdx ] = jdx;
    >
    > In that regard, the result now becomes:
    >
    > 16
    > JDX 0
    > vec_push.size() 16
    > JDX 1
    > vec_push.size() 16


    Using operator[] you can only access existing elements of a vector. It
    cannot create new ones. So it does not surprise me the the number of
    elements remains constant.

    HTH
    Heinz
     
    Heinz Ozwirk, Jan 9, 2006
    #3
  4. ma740988

    Daniel T. Guest

    In article <>,
    "ma740988" <> wrote:

    > Consider the source snippet
    >
    > int main()
    > {
    > std::vector<double> vec_push( 0x10 );
    > size_t const SZ = vec_push.size();
    > std::cout << vec_push.size() << std::endl;
    >
    > if ( SZ != 0x10 ) {
    > cout << " something's amiss " << endl;
    > return 0;
    > }
    >
    > vec_push.reserve(0x10000); // for test ..
    > for (size_t jdx(0); jdx < SZ; ++jdx)
    > {
    > vec_push.push_back( jdx );
    > std::cout << " JDX " << jdx << std::endl;
    > std::cout << " vec_push.size() " << vec_push.size() <<
    > std::endl;


    std::cout << "vec location: " << &vec_push[0] << std::endl;

    > }
    > std::cout << vec_push.size() << std::endl;
    > }


    > At issue: The results from the program suggest that - with each call
    > to push_back the vector re-allocates. A bit of a mystery since I've
    > already allocated enough space with reserve


    On my system each call does not re-allocate the space in your program.
    You aren't outputing enough information to make the determination on
    your system. Try adding the line I placed in your program and see what
    the output is...

    You will likely notice that the address of the first element of the
    vector does not change, which proves that the block of memory was not
    moved.
     
    Daniel T., Jan 9, 2006
    #4
  5. ma740988

    ma740988 Guest

    || Size and capacity are not the same. Capacity is the actual number of

    || objects available before another resize is necessary, while size
    is
    || the actual number of objects already assigned.

    Never mind. I caught my error. I've already made room for 16 objects.
    So of course each call to push_back will create 16 more. I already
    understood the distinction between size and capacity. This is one of
    those items in source, where the construct threw me for a loop. One
    of those things where you might have wanted ++i as opposed to i++ :)
     
    ma740988, Jan 9, 2006
    #5
  6. ma740988

    Earl Purple Guest

    Zara wrote:
    > /* added */
    > std::cout << " vec_push.capacity() " << vec_push.capacity() <<
    > std::endl;
    > /* end of additions */
    > > }
    > > std::cout << vec_push.size() << std::endl;
    > >}


    You could also output static_cast<void *>( &vec_push[0] ) (as long as
    vec_push is not empty which it never is).

    That will show you the address of the first element in your vector and
    you will be able to see whether or not it moves.
     
    Earl Purple, Jan 9, 2006
    #6
  7. ma740988

    Howard Guest


    >
    > You will likely notice that the address of the first element of the
    > vector does not change, which proves that the block of memory was not
    > moved.


    That doesn't neccessarily prove that the vector was not re-allocated. It's
    _possible_ that memory could be allocated at the same address.

    -Howard
     
    Howard, Jan 9, 2006
    #7
  8. ma740988

    Daniel T. Guest

    In article <uHBwf.443180$>,
    "Howard" <> wrote:

    > >
    > > You will likely notice that the address of the first element of the
    > > vector does not change, which proves that the block of memory was not
    > > moved.

    >
    > That doesn't neccessarily prove that the vector was not re-allocated. It's
    > _possible_ that memory could be allocated at the same address.
    >
    > -Howard


    True, but simply printing the capacity doesn't work either. It's
    _possible_ that the vector was re-allocated but made the same size.

    Come to think about it, even knowing the capacity *and* the location of
    the first element isn't enough, it's _possible_ that the system
    allocated the memory in another place then put it back to the original
    location.
     
    Daniel T., Jan 10, 2006
    #8
  9. ma740988

    Shezan Baig Guest

    Daniel T. wrote:
    > True, but simply printing the capacity doesn't work either. It's
    > _possible_ that the vector was re-allocated but made the same size.



    Not in the case of push_back. If v.size() < v.capacity(), then
    v.push_back(...) must NOT allocate. Otherwise v.reserve(...) would be
    meaningless.

    -shez-
     
    Shezan Baig, Jan 10, 2006
    #9
    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. Ganesh Gella
    Replies:
    5
    Views:
    1,232
    John Harrison
    Jul 14, 2003
  2. Hitesh Bhatiya
    Replies:
    4
    Views:
    4,551
    John Harrison
    Aug 13, 2003
  3. Avi Bercovich
    Replies:
    5
    Views:
    23,679
    Evan Carew
    Jan 14, 2004
  4. Replies:
    8
    Views:
    1,967
    Csaba
    Feb 18, 2006
  5. Jeff
    Replies:
    9
    Views:
    575
Loading...

Share This Page