?
Solved

Deep Copy vs Shallow copy

Posted on 2009-12-17
7
Medium Priority
?
938 Views
Last Modified: 2013-12-14
Hi Experts,

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

Thank you.
0
Comment
Question by:ambuli
7 Comments
 
LVL 86

Expert Comment

by:jkr
ID: 26074462
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
 

Author Comment

by:ambuli
ID: 26074518
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
 
LVL 86

Expert Comment

by:jkr
ID: 26074576
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
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 9

Expert Comment

by:magicdlf
ID: 26078680
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
 
LVL 2

Expert Comment

by:aquadeep
ID: 26106796
0
 
LVL 32

Expert Comment

by:phoffric
ID: 26108115
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
 
LVL 2

Accepted Solution

by:
aquadeep earned 2000 total points
ID: 26111972
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

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Update (December 2011): Since this article was published, the things have changed for good for Android native developers. The Sequoyah Project (http://www.eclipse.org/sequoyah/) automates most of the tasks discussed in this article. You can even fin…
This article shows you how to optimize memory allocations in C++ using placement new. Applicable especially to usecases dealing with creation of large number of objects. A brief on problem: Lets take example problem for simplicity: - I have a G…
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.
Suggested Courses

864 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question