What is the problem if copy constructor has mem copy?

D

doublemaster007

A(A &a) { memcopy(this &a, sizeof(A) ;}

Why we should not do this?? Is it because it spoils vtable??
 
M

Michael Mol

A(A &a) { memcopy(this &a, sizeof(A) ;}

Why we should not do this?? Is it because it spoils vtable??

Perhaps. vtables are implementation-dependent, so it's best not to
risk it.

There's also the concern of whether A has any members with non-
trivial constructors. Consider this example:

struct B
{
char* pMem;
B()
{
pMem = new char[10];
}
~B()
{
delete[] pMem;
}
};

struct A
{
B m_BMember;
A(A &a)
{
memcpy(this, &a, sizeof(A));
}
};


If you instantiate A and delete it, you're fine; B's constructor and
destructor will behave normally. But if you instanciate A, and then
use your copy constructor to copy the contents of a second A, then
your B's member variables will be copied as well--meaning you now have
two instances of B which will each call the delete[] operator on the
same pointer when they're destroyed. And that's a serious bug.

vtable issues aside, unless you know with absolute certainty the
behavior of your base, derived and member classes, memcpy is *not* the
way to go. And even then, don't risk making a habit of it; There are
probably more gotchas that I haven't mentioned.
 
M

Muhammed

A(A &a) { memcopy(this &a, sizeof(A) ;}
Why we should not do this?? Is it because it spoils vtable??

Perhaps.  vtables are implementation-dependent, so it's best not to
risk it.

There's also the concern of  whether A has any members with non-
trivial constructors.  Consider this example:

struct B
{
  char* pMem;
  B()
  {
    pMem = new char[10];
  }
  ~B()
  {
    delete[] pMem;
  }

};

struct A
{
  B m_BMember;
  A(A &a)
  {
    memcpy(this, &a, sizeof(A));
  }

};

If you instantiate A and delete it, you're fine; B's constructor and
destructor will behave normally.  But if you instanciate A, and then
use your copy constructor to copy the contents of a second A, then
your B's member variables will be copied as well--meaning you now have
two instances of B which will each call the delete[] operator on the
same pointer when they're destroyed.  And that's a serious bug.

vtable issues aside, unless you know with absolute certainty the
behavior of your base, derived and member classes, memcpy is *not* the
way to go.  And even then, don't risk making a habit of it; There are
probably more gotchas that I haven't mentioned.

Thank yo so much. If you keep vtable problem aside basically it does
the shallow copy. which otherwise dafault constructor does. Isnt it??
Memcopy is like bitwose copy, which compiler gen constructor otherwise
do. So i am not finding any problem here. Am i missing some thing?

Or is it that even compiler generated copy constructor has the same
problem in the example you have mentioned.

One more thing. I have read some were that problem i mentioned would
spoil vtables. ut i could not find how, why. Can any one pls explain
this?
 
M

Michael Mol

Perhaps.  vtables are implementation-dependent, so it's best not to
risk it.
There's also the concern of  whether A has any members with non-
trivial constructors.  Consider this example:
struct B
{
  char* pMem;
  B()
  {
    pMem = new char[10];
  }
  ~B()
  {
    delete[] pMem;
  }

struct A
{
  B m_BMember;
  A(A &a)
  {
    memcpy(this, &a, sizeof(A));
  }

If you instantiate A and delete it, you're fine; B's constructor and
destructor will behave normally.  But if you instanciate A, and then
use your copy constructor to copy the contents of a second A, then
your B's member variables will be copied as well--meaning you now have
two instances of B which will each call the delete[] operator on the
same pointer when they're destroyed.  And that's a serious bug.
vtable issues aside, unless you know with absolute certainty the
behavior of your base, derived and member classes, memcpy is *not* the
way to go.  And even then, don't risk making a habit of it; There are
probably more gotchas that I haven't mentioned.

Thank yo so much. If you keep vtable problem aside basically it does
the shallow copy. which otherwise dafault constructor does. Isnt it??
Memcopy is like bitwose copy, which compiler gen constructor otherwise
do. So i am not finding any problem here. Am i missing some thing?

Or is it that even compiler generated copy constructor has the same
problem in the example you have mentioned.

In the example I mentioned, I expect a good compiler would run B's
copy constructor as part of its generated copy constructor for A. And
since I didn't provide B with a copy constructor, yes, it would have
the same problem. However, a programmer writing proper code would have
included an appropriate copy constructor for B, in which case the
compiler's generated copy constructor for A would have been fine.
One more thing. I have read some were that problem i mentioned would
spoil vtables. ut i could not find how, why. Can any one pls explain
this?

vtables are implementation specific, meaning that anything you do to
interact with them directly, if not done through syntactic constructs
provided by the standard, is undefined behavior. Let's say there's
some compiler out there whose vtable data assumes that the vtable has
a specific place in memory (such as if it had relative offsets for
function pointers, for example.)...If you move that vtable in memory,
you've broken those pointers and are going to have Bad Things happen.

But in that example, I'm assuming an implementation detail of some
hypothetical compiler. The point of Undefined Behavior is that you
can't assume anything about it if you plan to support more than one
specific version of one specific compiler on one specific platform
with one specific configuration environment--In other words, you can't
assume *anything* about it, and so you shouldn't assume that it's
safe.

If it works on your computer, so be it. But don't hand the code or
binaries to someone else and tell them it will work on theirs, and
don't expect it to work under any other circumstances than the ones
under which you built it and ran it.
 
J

James Kanze

A(A &a) { memcopy(this &a, sizeof(A) ;}
Why we should not do this?? Is it because it spoils vtable??

Because it's undefined behavior (assuming you mean memcpy, and
not memcopy). Depending on the class A, and where it is used,
any number of things could happen---none of them good.
 

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,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top