• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 943
  • Last Modified:

Deep Copy vs Shallow copy

Hi Experts,

Could you please give me a quick simple example of deep copy vs shallow copy.

Thank you.
0
ambuli
Asked:
ambuli
1 Solution
 
jkrCommented:
An example would be

class A
{
 string s;
};
A a;
A b;
a=b; //deep copy
memcpy(&a,&b,sizeof(A)); // shallow copy

Also check out http://www.devx.com/tips/Tip/13625 ("Deep Copy and Shallow Copy" - that's where the example comes from) and http://en.wikipedia.org/wiki/Object_copy for further information

0
 
ambuliAuthor Commented:
Thanks Jkr.  Sorry, I wasn't clear enough.  I just want to understand how we eliminate shallow copy using a copy constructor.  I read that the default copy constructor does a shallow copy.  
0
 
jkrCommented:
Well, in that case, maybe the example should be a bit more complex, e.g.
class A
{
 // members
 string s;
 vector<string> vs;

  A& assign(const A& a) // helper to be used by both the copy ctor and assignment operator
  {
    // copy each member
    s = a.s;
    vs = a.vs;
  }

public:

  A(const A& a) // copy constructor
  {
    assign(a);
  }

  A& operator=(const A& a) // assignment operator
  {
    return assign(a);
  }

};

Open in new window

0
Cloud Class® Course: Microsoft Exchange Server

The MCTS: Microsoft Exchange Server 2010 certification validates your skills in supporting the maintenance and administration of the Exchange servers in an enterprise environment. Learn everything you need to know with this course.

 
magicdlfCommented:
For example, you have a pointer in a structure(or class)
struct node
{
       char* ptr;
};
In copy constructor, if you copy the ptr itself, it's a shallow copy. If you allocate a new memory, copy the content of the string, that's a deep copy.  
0
 
aquadeepCommented:
0
 
phoffricCommented:
The ShallowCopy and DeepCopy classes differ in that the DeepCopy class contains a copy constructor. Here is the output when running this program:

 *sc.pb 43   *sc2.pb 43
 *dc.pb 22   *dc2.pb 44

Notice that when we execute the line:
     *sc2.pb = 43;
then *sc.pb has the same value. If this is desired, then fine. But if you require that the value pointed to by sc.pb be maintained independent of operations on sc2, then a deep copy is in order. The DeepCopy class copy constructor allocates its own memory for pb, and changing one object of DeepCopy does not affect the value in another object of DeepCopy.
#include <iostream>
using namespace std;

class ShallowCopy {
public:
	ShallowCopy( int aa, int* pp): a(aa), pb(pp) {}

	int a;
	int * pb;
};

class DeepCopy{
public:
	DeepCopy( int aa, int* pp): a(aa), pb(pp) {}
	DeepCopy( const DeepCopy &d ) {
		this->a = d.a;
		this->pb = new int(*d.pb);
	}

	int a;
	int * pb;
};

void main() {
	int * pIntDeep   = new int;
	int * pIntShallow = new int;

	*pIntShallow = 22;
	*pIntDeep   = 22;

	ShallowCopy sc( 2, pIntShallow );
	ShallowCopy sc2(sc);
	*sc2.pb = 43;

	DeepCopy dc( 1, pIntDeep   );
	DeepCopy dc2(dc);
	*dc2.pb = 44;

	cout << " *sc.pb " << *sc.pb << "   *sc2.pb " << *sc2.pb << endl;
	cout << " *dc.pb " << *dc.pb << "   *dc2.pb " << *dc2.pb << endl;
}

Open in new window

0
 
aquadeepCommented:
One should use deep copy (i.e. define your own copy constructor/assignment operator) if a class has dynamic memory allocation. The given example shows why.

By using copy constructor/assignment operator, we usually want to create a new independent object but with same values. But if we use shallow copy (i.e. default functions provided by compiler), then while creating a new object, the dynamic members are not getting created properly. In shallow copy, we are using the memory allocated to the original object for the new object's members too. This way, both the object are connected to each other, they are not independent.

The following example uses shallow copy and notice that the value of t1->str and t2->str are same. The output of the code given is:

10, Bi
20, Bi


While if the objects would have used deep copy and would have been independent, the result should have been as:

10, Hi
20, Bi

#include <iostream>
using namespace std;

class test
{
public:
	int a;
	char* str;
};

int main()
{
	char* s1 = "Hi";
	char* s2 = "Bi";
	test *t1 = new test();
	t1->a = 10;
	t1->str = new char(20);
	strcpy(t1->str, s1);

	test *t2 = new test(*t1);
	t2->a = 20;
	strcpy(t2->str, s2);
	
	cout << t1->a << ", " << t1->str << endl;
	cout << t2->a << ", " << t2->str << endl;
}

Open in new window

0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Introducing Cloud Class® training courses

Tech changes fast. You can learn faster. That’s why we’re bringing professional training courses to Experts Exchange. With a subscription, you can access all the Cloud Class® courses to expand your education, prep for certifications, and get top-notch instructions.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now