vector push_back question

M

ma740988

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
 
Z

Zara

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 */
 
H

Heinz Ozwirk

ma740988 said:
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 ....

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
 
D

Daniel T.

"ma740988 said:
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.
 
M

ma740988

|| 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++ :)
 
E

Earl Purple

Zara said:
/* added */
std::cout << " vec_push.capacity() " << vec_push.capacity() <<
std::endl;
/* end of additions */

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.
 
H

Howard

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
 
D

Daniel T.

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[/QUOTE]

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.
 
S

Shezan Baig

Daniel said:
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-
 

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

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top