Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

C++ Shallow and Deep Copy Mechanics

Tech Apr 26 21

Shallow Copy vs Deep Copy

Shallow Copy Mechanics

Shallow copying occurs when multiple pointers reference the identical memory address. Altering the data through any of these pointers modifies the underlying memory, affecting all other pointers pointing to that location.

Procedural Shallow Copy Illustration

Consider an array of character pointers storing inputs:

#include <iostream>

int main() {
    char tempBuffer[64];
    const char* wordRefs[3];

    for (int idx = 0; idx < 3; ++idx) {
        std::cin >> tempBuffer;
        wordRefs[idx] = tempBuffer; // Shallow assignment
    }

    for (int idx = 0; idx < 3; ++idx) {
        std::cout << wordRefs[idx] << " ";
    }
    return 0;
}

Entering Alpha Beta Gamma produces the output Gamma Gamma Gamma. Assume tempBuffer resides at memory address 0x100.

  1. Alpha is read into 0x100, and wordRefs[0] is assigned 0x100.
  2. Beta overwrites 0x100, and wordRefs[1] points to 0x100.
  3. Gamma overwrites 0x100, and wordRefs[2] points to 0x100. Upon iteration, all elements read from 0x100, yielding the last input string Gamma.

Object-Oriented Shallow Copy Illustration

When a class manages dynamically allocated memory, default copy operations perform shallow copying.

#include <iostream>
#include <cstring>

class TextBuffer {
private:
    char* data;
public:
    TextBuffer(const char* input) {
        data = new char[std::strlen(input) + 1];
        std::strcpy(data, input);
    }

    void modify(const char* input) {
        delete[] data;
        data = new char[std::strlen(input) + 1];
        std::strcpy(data, input);
    }

    void display() const {
        std::cout << data << std::endl;
    }
};

int main() {
    TextBuffer instanceA{"Original text"};
    instanceA.display();

    TextBuffer instanceB = instanceA; // Default copy constructor
    instanceB.display();

    instanceB.modify("Updated text");
    instanceB.display();
    instanceA.display();

    return 0;
}

Executing this snippet demonstrates unintended side effects. instanceB is initialized from instanceA via the default copy constructor, copying the pointer data. Both objects now reference the identical heap allocation. Calling instanceB.modify("Updated text") deallocates the shared memory and assigns instanceB.data to a new block. Because instanceA.data retains the original (now dangling) address, any subsequent access like instanceA.display() yields undefined behavior—often outputting the newly written string if the allocator reuses the same memory block, or causing a crash.

Deep Copy Mechanics

Deep copying resolves this by allocating distinct memory blocks for each pointer before copying the actual data.

Procedural Deep Copy Illustration

Refactoring the previous procedural example requires explicit memory allocation and data duplicatoin:

#include <iostream>
#include <cstring>

int main() {
    char tempBuffer[64];
    char* wordRefs[3];

    for (int idx = 0; idx < 3; ++idx) {
        std::cin >> tempBuffer;
        // Allocate independent memory
        wordRefs[idx] = new char[std::strlen(tempBuffer) + 1];
        // Copy the content
        std::strcpy(wordRefs[idx], tempBuffer);
    }

    for (int idx = 0; idx < 3; ++idx) {
        std::cout << wordRefs[idx] << " ";
    }

    // Release allocated memory
    for (int idx = 0; idx < 3; ++idx) {
        delete[] wordRefs[idx];
    }
    return 0;
}

Inputs Alpha Beta Gamma now correctly output Alpha Beta Gamma. Each string receives a dedicated heap allocation via new char[], ensuring wordRefs elements point to isolated memory regions. The std::strcpy functon transfers the string payload into these unique buffers. Finally, delete[] deallocates each individual buffer to prevent memory leaks.

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Understanding the MP4 File Format and Analysis

Table of Contents Overview Fundamentals of the MP4 Format Key Concepts of the Container Format Box Structure Track Samples Sample Tables Chunks Detailed Explanation of Core Boxes Additional Boxes...

Android OpenGL ES – Camera Preview and Recording with Filters

This article demonstrates a combination of OpenGL ES, camera integration, and real-time filter application on textures. The objective is to preview camera feeds, apply filters, and record the output s...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.