×

Search anything:

Deep vs Shallow Copy in C++

C++

Internship at OpenGenus

Get this book -> Problems on Array: For Interviews and Competitive Programming

In programming, when we work with data objects, we often need to make copies of them for various purposes like storing or modifying them. However, the way we copy an object can have different consequences on how the copied object behaves and interacts with the original one.

Two common types of copying objects in programming are shallow copy and deep copy and we will discuss them in this article at OpenGenus.

There will also be a BONUS SECTION in the end for readers who want to prepare for coding interviews.

Shallow Copy

In C++, a shallow copy is a type of copy where a new object is created that is a replica of the original object. However, the new object only copies the values of the member variables of the original object without creating new copies of the memory space occupied by those variables.
Here is an example of shallow copying in C++:


// opengenus.cpp 
#include <iostream>
using namespace std;

class MyClass {
public:
    int* myArray;
    int size;

    MyClass(int s) {
        size = s;
        myArray = new int[size];
        for (int i = 0; i < size; i++) {
            myArray[i] = i;
        }
    }

    // Shallow copy constructor
    MyClass(const MyClass& other) {
        size = other.size;
        myArray = other.myArray;
    }
};
                                 
int main() {
    // Create original object
    MyClass original(5);

    // Create copy of original object using shallow copy
    MyClass shallowCopy(original);

    // Modify copy
    shallowCopy.myArray[0] = 100;

    // Verify that both objects have been modified
    cout << original.myArray[0] << endl; // Output: 100
    cout << shallowCopy.myArray[0] << endl; // Output: 100

    return 0;
}

The shallow copy constructor simply copies the values of size and myArray from the original object to the new object.We create a shallow copy of the original object by passing it to the shallow copy constructor. We modify the first element of the shallow copy to 100 and verify that both the original and the shallow copy have been modified. This is because the shallow copy only copied the memory address of the myArray variable, so both objects are still pointing to the same memory space.

Deep Copy

In C++, a deep copy is a type of copy operation where a new object is created that is an exact replica of the original object, but with separate memory allocation for its member variables. This means that a deep copy creates a new copy of all the data stored in the original object, including any dynamically allocated memory.

Here is an example of deep copying in C++:

//opengenus.cpp

#include <iostream>
using namespace std;

class MyClass {
public:
    int* myArray;
    int size;

    MyClass(int s) {
        size = s;
        myArray = new int[size];
        for (int i = 0; i < size; i++) {
            myArray[i] = i;
        }
    }

    // Deep copy constructor
    MyClass(const MyClass& other) {
        size = other.size;
        myArray = new int[size];
        for (int i = 0; i < size; i++) {
            myArray[i] = other.myArray[i];
        }
    }

    // Destructor
    ~MyClass() {
        delete[] myArray;
    }
};

int main() {
    // Create original object
    MyClass original(5);

    // Create copy of original object using deep copy
    MyClass deepCopy(original);

    // Modify copy
    deepCopy.myArray[0] = 100;

    // Verify that only the copy has been modified
    cout << original.myArray[0] << endl; // Output: 0
    cout << deepCopy.myArray[0] << endl; // Output: 100

    return 0;
}

The deep copy constructor creates a new memory allocation for myArray and copies the values of size and myArray from the original object to the new object. We then create a deep copy of the original object by passing it to the deep copy constructor. We modify the first element of the deep copy to 100 and verify that only the copy has been modified. This is because the deep copy created a new memory allocation for myArray, so the modification to the copy does not affect the original object.

Conclusion

The choice between shallow and deep copying depends on the specific needs of the program. Shallow copying can be more efficient and faster since it does not create new copies of all the data. However, it can lead to unintended consequences when changes made to the copied object affect the original object. Deep copying, on the other hand, creates a completely separate object but can be slower and require more memory.
In conclusion, shallow copy and deep copy are two common ways of copying objects in programming. Understanding the differences between these two types of copying can help programmers choose the appropriate one for their specific needs, and avoid unexpected behavior in their programs.

Bonus Section

INTERVIEW PROBLEM

Write code in c++ to create a deep copy of graph. In this problem, a reference of a node in a connected undirected graph is provided and we need to write a function to do a deep copy of the graph using the given node.

Each node has two member variables:

  • value
  • list of directly connected nodes

The Algorithm of any deep copy problem :

  1. Create a map of Org node - Clone node pairs to prevent redundant recursion calls
  2. Run a Depth first seach on the graph using a helper function and return it
  3. For each node create a new copy node and mark them visited in map
  4. Iterate over all children of org node and mark the edges for copy graph
  5. If childnode is not in map , we will extend the copy graph edge by doing a fresh dfs on the unvisited child node of org graph
  6. Else simply extend the clone graph using stored copynode in map
  7. Return the root node of copy graph from helper function.
    You can upsolve deep cloning linkedlist also using this concept

C++ CODE:

//clonegraph.cpp

class Solution {
public:
    
    Node* dfs(Node* node,  unordered_map<Node*,Node*>&mp){
        
        if(!node)return NULL;
        //mark visisted
        //create a new node
        Node* root=new Node(node->val);
        
        mp[node]=root;
     
        for(auto n: node->neighbors){
            
            if(mp.find(n)==mp.end()){
                 
                root->neighbors.push_back(dfs(n,mp));                
                
            }
            else{
                //if already in map
                root->neighbors.push_back(mp[n]); //new nodes are stored in mapp
            }
           
        }
        
        return root;
        
    }
    
    Node* cloneGraph(Node* node) {
       
        unordered_map<Node*,Node*>mp;
        
        return dfs(node,mp);
           
    }
};

Thank you for reading through hoped you liked the post Do Upvote and Share with your friends if you found this useful.

Deep vs Shallow Copy in C++
Share this