Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

C++ Shallow and Deep Copy Mechanics

Tech 1

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...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

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