Re: Am I misusing std::vector?
loose AT astron DOT nl wrote:
Hi,
I was surprised by the output of the program below. From what I
understand from the C++ STL documentation, vector<T>::resize(N), will
create N *newly constructed* objects of T.
Yes, it will. They'll be copy constructed.
So, I expected *v[0].ip to
be equal to 0, and *v[sz-1].ip equal to -77.
Ah; you're expecting each one to be default-constructed.
resize(N) is actually just resize(N, A()); here (there's
a default argument, or an overload that does something
just about equivalent). There's only one use of the
default constructor.
However, I discovered,
using a few different compilers (two different versions of gcc, and
icc), that both return -77. It turns out that only *one* object is
being constructed and this one object seems to be bitwise copied to the
other members.
According to the standard it is copied, but bitwise copy
is an optimization only, given that there's a default
copy constructor (as you didn't declare one). In the
case of an object with a single pointer field, the as-if
rule certainly allows bitwise copying as it has the same
effect as memberwise copying.
See my code below and try it for yourself.
Am I missing something here?
You could check the documentation for resize in a little
more detail.
You should also look into the "rule of three", as your
code has a bug in this area -- when copying, you allow
objects to share ownership of the same dynamically
allocated object, and they *all* call delete for it,
which will crash on many systems.
Regards,
Marcel Loose.
<code>
#include <vector>
#include <iostream>
using namespace std;
struct A
{
A(int i = 0) { ip = new int(i); }
~A() { delete ip; }
To see what's happening, add
A(A const& rhs) : ip(rhs.ip) { std::cout << "Copied an A\n"; }
here. (But note that there's still a bug in the destructor.)
int* ip;
};
int main()
{
const unsigned sz = 1000000;
vector<A> v;
v.resize(sz);
*v[sz-1].ip = -77;
cout << "v.size() = " << v.size() << endl;
cout << "v[0].ip = " << v[0].ip << "; " << "*v[0].ip = " <<
*v[0].ip << endl;
cout << "v[sz-1].ip = " << v[sz-1].ip << "; " << "*v[sz-1].ip = "
<< *v[sz-1].ip << endl;
return 0;
}
</code>
Hope this help,
-- James
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]