By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,305 Members | 1,764 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,305 IT Pros & Developers. It's quick & easy.

Why is the copy ctor called twice here?

P: n/a
The output of this:

#include <iostream>
#include <vector>
using namespace std;

struct X {
int i;
X(const X& x) : i(x.i) {
cout << "ctor copy: " << i << endl;
}
X(int ii) : i(ii) {
cout << "ctor by int: " << i << endl;
}
~X() {
cout << "dtor: " << i << endl;
}
};

int main(int argc, char **argv) {

vector<X> v;
v.push_back(X(100));

return 0;
}

Is this:

ctor by int: 100
ctor copy: 100
ctor copy: 100
dtor: 100
dtor: 100
dtor: 100

When you do the push_back, I can understand the vector wanting to make
its own copy, but why is this apparently done twice?

Jul 23 '05 #1
Share this Question
Share on Google+
10 Replies


P: n/a
ri***********@yahoo.co.uk wrote:

The output of this:

#include <iostream>
#include <vector>
using namespace std;

struct X {
int i;
X(const X& x) : i(x.i) {
cout << "ctor copy: " << i << endl;
}
X(int ii) : i(ii) {
cout << "ctor by int: " << i << endl;
}
~X() {
cout << "dtor: " << i << endl;
}
};

int main(int argc, char **argv) {

vector<X> v;
v.push_back(X(100));

return 0;
}

Is this:

ctor by int: 100
ctor copy: 100
ctor copy: 100
dtor: 100
dtor: 100
dtor: 100

When you do the push_back, I can understand the vector wanting to make
its own copy, but why is this apparently done twice?


From the language point of view, there is no specific reason. Ask in a newsgroup
dedicated to your particular compiler. It could be an error in its vector-implementation.

--
Karl Heinz Buchegger
kb******@gascad.at
Jul 23 '05 #2

P: n/a
ri***********@yahoo.co.uk wrote:
The output of this:
<snip program>
Is this:

ctor by int: 100
ctor copy: 100
ctor copy: 100
dtor: 100
dtor: 100
dtor: 100

When you do the push_back, I can understand the vector wanting to make
its own copy, but why is this apparently done twice?


On my compiler (g++ 3.3), I get what you would expect, namely:

ctor by int: 100
ctor copy: 100
dtor: 100
dtor: 100

I am unsure why your vector is behaving differently. It is possible
push_back takes it's input by value rather than by reference (which
would be wrong), or that the vector is deciding to extend earlier than
is necessary (which would also be wrong), or something else. You could
if you wish explore this by looking at the source to vector, which
should be included in your compiler (as very few compilers can compile
templates seperatly and therefore include the source in the headers).

Unfortunatly I suspect it's unlikely such a bug would be fixed so you
may have to upgrade your compiler (although you can always report it)

Chris
Jul 23 '05 #3

P: n/a
"Chris Jefferson" <ca*@cs.york.ac.uk> wrote in message
news:cu**********@pump1.york.ac.uk...
ri***********@yahoo.co.uk wrote:
The output of this:
<snip program>
Is this:

ctor by int: 100
ctor copy: 100
ctor copy: 100
dtor: 100
dtor: 100
dtor: 100

When you do the push_back, I can understand the vector wanting to make
its own copy, but why is this apparently done twice?


On my compiler (g++ 3.3), I get what you would expect, namely:

ctor by int: 100
ctor copy: 100
dtor: 100
dtor: 100


Odd! On my compiler (g++ 3.4.2) I get
ctor by int: 100
ctor copy: 100
dtor: 100

Something is afoot!
--
Gary
Jul 23 '05 #4

P: n/a
ri***********@yahoo.co.uk wrote:
...
int main(int argc, char **argv) {

vector<X> v;
v.push_back(X(100));

return 0;
}

Is this:

ctor by int: 100
ctor copy: 100
ctor copy: 100
dtor: 100
dtor: 100
dtor: 100

When you do the push_back, I can understand the vector wanting to make
its own copy, but why is this apparently done twice?


It is possible that the first copy is made when the compiler initializes
the [constant reference] parameter of 'push_pack' with a temporary
object 'X(100)'. 'X(100)' is not an lvalue, which means that in
accordance with 8.5.2/5 the compiler is allowed to create an extra copy
of the object when initializing that reference (actually, in this case
the compiler is allowed create as many extra copies as it wants).

The second copy constructor call takes place when the parameter of
'push_pack' is transferred to the actual vector memory.

Apparently, some internal quirk of the compiler caused it to create that
unnecessary first copy (although there's nothing illegal in it). AFAIK,
most compilers won't do it.

--
Best regards,
Andrey Tarasevich
Jul 23 '05 #5

P: n/a
Why would push_back taking input by value be wrong?

Regards
Senthil

Jul 23 '05 #6

P: n/a
"sadhu" <se**********@wdevs.com> wrote in message
news:11**********************@l41g2000cwc.googlegr oups.com...
Why would push_back taking input by value be wrong?


Because the C++ standard defines its parameter
as a const reference.

=============================
ISO/IEC 14882:1998(E)

23.2.4 Template class vector

// 23.2.4.3 modifiers:
void push_back(const T& x);
=============================
-Mike
Jul 23 '05 #7

P: n/a
I think this is shabby re-allocation on the MS compiler (it is MS we're
talking about here right?)

if you provide a default constructor for X, and replace your main with:
int main(int argc, char** argv)
{
const X & x1(100);

vector<X> v;

v.reserve(1);

std::cout << "\n\n" << std::endl;

v.push_back(x1);

return 0;

}

You can get a clearer idea of where the copies are taking place - explicitly
instantiating as a reference removes any copy it may have caused when
created via the push_back parameter - and yet if you remove the reserve(1)
the same behaviour you are seeing repeats - which means in my book it's just
bad re-allocation when inserting in the vector.
regards,

Aiden.

<ri***********@yahoo.co.uk> wrote in message
news:11*********************@f14g2000cwb.googlegro ups.com...
The output of this:

#include <iostream>
#include <vector>
using namespace std;

struct X {
int i;
X(const X& x) : i(x.i) {
cout << "ctor copy: " << i << endl;
}
X(int ii) : i(ii) {
cout << "ctor by int: " << i << endl;
}
~X() {
cout << "dtor: " << i << endl;
}
};

int main(int argc, char **argv) {

vector<X> v;
v.push_back(X(100));

return 0;
}

Is this:

ctor by int: 100
ctor copy: 100
ctor copy: 100
dtor: 100
dtor: 100
dtor: 100

When you do the push_back, I can understand the vector wanting to make
its own copy, but why is this apparently done twice?


Posted Via Usenet.com Premium Usenet Newsgroup Services
----------------------------------------------------------
** SPEED ** RETENTION ** COMPLETION ** ANONYMITY **
----------------------------------------------------------
http://www.usenet.com
Jul 23 '05 #8

P: n/a
adbarnet wrote:

if you provide a default constructor for X, and replace your main with:
Why do you think 'X' needs a default constructor? In the code below I
don't see any place where it might be necessary.
int main(int argc, char** argv)
{
const X & x1(100);

vector<X> v;

v.reserve(1);

std::cout << "\n\n" << std::endl;

v.push_back(x1);

return 0;

}


--
Best regards,
Andrey Tarasevich
Jul 23 '05 #9

P: n/a
Quite right - it's not required.

regards,

Aiden

"Andrey Tarasevich" <an**************@hotmail.com> wrote in message
news:11*************@news.supernews.com...
adbarnet wrote:

if you provide a default constructor for X, and replace your main with:


Why do you think 'X' needs a default constructor? In the code below I
don't see any place where it might be necessary.
int main(int argc, char** argv)
{
const X & x1(100);

vector<X> v;

v.reserve(1);

std::cout << "\n\n" << std::endl;

v.push_back(x1);

return 0;

}


--
Best regards,
Andrey Tarasevich


Posted Via Usenet.com Premium Usenet Newsgroup Services
----------------------------------------------------------
** SPEED ** RETENTION ** COMPLETION ** ANONYMITY **
----------------------------------------------------------
http://www.usenet.com
Jul 23 '05 #10

P: n/a

"Gary Labowitz" <gl*******@comcast.net> wrote in message
news:VZ********************@comcast.com...
"Chris Jefferson" <ca*@cs.york.ac.uk> wrote in message
news:cu**********@pump1.york.ac.uk...
ri***********@yahoo.co.uk wrote:
The output of this:
<snip program>
Is this:

ctor by int: 100
ctor copy: 100
ctor copy: 100
dtor: 100
dtor: 100
dtor: 100

When you do the push_back, I can understand the vector wanting to make
its own copy, but why is this apparently done twice?


On my compiler (g++ 3.3), I get what you would expect, namely:

ctor by int: 100
ctor copy: 100
dtor: 100
dtor: 100


Odd! On my compiler (g++ 3.4.2) I get
ctor by int: 100
ctor copy: 100
dtor: 100

Something is afoot!
--
Gary

I noticed similar behavior when I ran this example in VC++, I was a little
curious why the destructor calls
didn't match the constructor calls. I had a breakpoint on the main return
statement, and only saw the one destructor call. However, if you continue
after the return, the second
destructor is triggered as we leave the main() scope. The behavior you
reported above is certainly incorrect
otherwise.

dave


Oct 2 '05 #11

This discussion thread is closed

Replies have been disabled for this discussion.