Deep Copy and Shallow Copy in C++

Deep Copy and Shallow Copy in C++

The definition of deep copy and shallow copy is given below:

Creating a copy of object by copying data of all member variables as it is, is called shallow copy while creating an object by copying data of another object along with the values of memory resources resides outside the object but handled by that object, is called deep copy.


Shallow copy is also known as a bitwise copy. It involves copying values of an object to another object without duplicating dynamically allocated memory. You can say that it creates a new object but does not replicate the content pointed to by the pointers within the original object.


Deep copy involves creating a complete replica of an object which also includes any dynamically allocated memory. It ensures that the new object has its own copy of dynamically allocated resources rather than just copying the addresses of those reosources.


Let us first understand some basic points that you should aware of before knowing about shallow copy and deep copy in details.


Understanding the Differences:

Let's understand the difference between deep copy and shallow copy with the help of following example:


Consider a class 'Person' with a dynamically allocated array to store their hobbies.

#include<iostream.h>
using namespace std;
class Person {
private:
    char *name;
    int *age;
public:
    Person(const char* n, int a) {
        name = new char[strlen(n) + 1];
        strcpy(name, n);
        age = new int;
        *age = a;
    }
    // Destructor and other member functions...
};

Now, let's create two objects using this class person1 and person2, and perform both shallow and deep copies.


#include<iostream.h>
Person person1("Saumya", 25);
Person person2 = person1; // Shallow Copy

In the case of shallow copy, 'person2' will have its own 'name' and 'age' pointers, but they will point to the same dynamically allocated memory locations as person1. Any modifications to the data pointed to by person2 will affect person1 and vice versa. It can lead to unexpected behavior and memory leaks if it is not handled properly.


#include<iostream.h>
Person person1("Saumya", 25);
Person person2 = person1; // Deep Copy

With deep copy, person2 will have its own separate copies of the dynamically allocated memory for name and age. Therefore, changes made to person2 will not affect person1. It provides more predictable behavior and prevents unintended side effects.


Best Practices and Use Cases:

Now that you understand the differences between deep copy and shallow copy, let's discuss about using each and the best practices for their implemention.


Shallow Copy:

Shallow copy is suitable when dealing with lightweight objects where copying the object's state is sufficient without duplicating dynamically allocated resources. It is faster and requires less memory. However, you should be cautious when using shallow copy to prevent unforeseen issues like memory leaks.


Deep Copy:

You should prefer Deep copy when working with complex objects that contain dynamically allocated memory or resources that should not be shared among multiple instances. It ensures data encapsulation. It prevents one objects' modifications from affecting others. Deep copy is generally used in complex data structures like linked lists, trees, or graphs.


Implementing Deep Copy and Shallow Copy in C++:

You can define copy constructors and assignment operators within your classes. It will help you implementing deep copy and shallow copy in C++. Here is how you can achieve this:


#include<iostream.h>
class Person {
private:
    char *name;
    int *age;
public:
    // Copy Constructor for Deep Copy
    Person(const Person& other) {
        name = new char[strlen(other.name) + 1];
        strcpy(name, other.name);
        age = new int;
        *age = *(other.age);
    }
    
    // Assignment Operator for Deep Copy
    Person& operator=(const Person& other) {
        if (this != &other) {
            delete[] name;
            delete age;
            name = new char[strlen(other.name) + 1];
            strcpy(name, other.name);
            age = new int;
            *age = *(other.age);
        }
        return *this;
    }
    
    // Destructor and other member functions...
};

For shallow copy, you can rely on the default copy constructor and assignment operator in C++. 


How can you create a copy of an object?

1. Default copy constructor is defined by the compiler when object of any class is created and there is no copy constructor defined in the program.

2. In addition to copy constructor, C++ compiler also overload copy assignment operator which is implemented when an object (after declaration) is initialized using "=" with another object of same class.

For Example:- copy assignment operator in c++
#include<iostream>
using namespace std;

class DummyClass
{
 private:
   int num1, num2;
 
 public:
  void setData(int x, int y)
   {
    num1 = x;
    num2 = y;
   }
   
   void showData()
    {
     cout << num1 << "  " << num2 << endl;
    }
   };
   
int main()
 {
  DummyClass D1;
  D1.setData(5, 11);
  D1.showData();
  
  //Copy constructor (created by compiler) will came in action here.
  DummyClass D2 = D1; 
  D2.showData();
    
  DummyClass D3;
  D3.setData(1, 11);
  D3.showData();
    
  DummyClass D4; 
  //Copy assignment operator overloaded by compiler came in action.
  D4 = D3;          
  D4.showData();
    
  return 0; 
 }

Output:
5  11
5  11
1  11
1  11

In the above example, object D4 is created and then it is initialized with object D3. In this case, copy assignment operator which is overloaded by compiler itself is implemented.

Points To Remember:-

When you create a copy of an object:
1. copy constructor will be called or
2. implicit copy assignment operator will be called.

When will Copy Constructor call?

When you initialize an object with another object of same class during its declaration, copy constructor will be called. You may read about Copy Constructor in details here : Copy Constructors in C++ Programming

For Example:-
#include<iostream>
using namespace std;

class DummyClass { 
 private:
  int num1, num2;
  
 public:
  void setData(int x, int y) {
   num1 = x;
   num2 = y;
  }
  
  void showData() {
   cout << num1 << "  " << num2 << endl;
  }
 };
 
int main() {
 DummyClass D1;
 D1.setData(5, 11); 
 D1.showData();
 
 //Copy constructor (created by compiler) will came in action here.
 DummyClass D2 = D1;  
 D2.showData();
}

When will Copy Assignment Operator call?

When you do not initialize an object during its declaration but initialize it after its declaration with another object of same class then copy assignment operator will be called.

For Example:-
#include<iostream>
using namespace std;
 
class DummyClass {
 private:
  int num1, num2;
  
 public:
  void setData(int x, int y) {
   num1 = x;
   num2 = y;
  }
  
  void showData() {
   cout << num1 << "  " << num2 << endl;
  }
 };
 
int main() {
 DummyClass D1;
 D1.setData(5, 11);
 D1.showData();
 
 DummyClass D2;
 //Copy assignment operator overloaded by compiler came in action.
 D2 = D1;          
 D4.showData();
}

Deep Copy and Shallow Copy in C++

1. Creating a copy of object by copying data of all member variables as it is, it is called shallow copy. The compiler will do shallow copy by default.

2. Creating an object by copying data of another object along with the values of memory resources resides outside the object but handled by that object, it is called deep copy.

Deep-copy-and-shallow-copy-in-cpp-learning-mania

For Example:- Deep Copy and Shallow Copy in c++
#include<iostream>
using namespace std;

class DummyClass {
 private:
  int num1, num2;
  int *ptr;
  
 public:
  DummyClass() {
   ptr = new int;
  }
  
  void setData(int x, int y, int z) {
   num1 = x;
   num2 = y;
   *ptr = z;
  }
  
  void showData() {
   cout << "A = " << num1 << " B = " << num2 << endl;
  }
  
  //copy constructor -> it is responsible for deep copy.
  DummyClass(DummyClass &D) {
   ptr = new int;
   num1 = D.num1;
   num2 = D.num2;
   *ptr = *(D.ptr);
  }
  
  //destructor -> to deallocate memory consumed by new pointer ptr. 
  ~DummyClass() {
   delete ptr;
  }
 };
 
int main() {
 DummyClass D1;
 D1.setData(3, 5, 11);
 D1.showData();
 
 //Copy constructor declared above will came in action and do deep copy.
 DummyClass D2 = D1;  
 D2.showData();
}

Output:
A = 3  B = 5
A = 3  B = 5 

What is Dangling Pointer in C++?

A pointer pointing to invalid adddress is called dangling pointer. There is a chance of program crash due to dangling pointer because it points to an invalid address. Dangling pointer points to a memory location that has been released or deallocated. 

Previous
Next Post »

2 comments

Click here for comments
sudent
admin
28 December ×

you have missed one line in Deepcopy example Copy constructor, you have to create memory for the pointer in Copy Constructor- ptr= new int;
otherwise it leads to segmentation fault, Really good information, Thanks for the Article

Reply
avatar
Nitish Sahni
admin
25 March ×

Thanks for the comment and Thanks a lot for letting us know the correction. It really helped us. We are thankful to you.

Reply
avatar