Shallow copy and deep copy in C
Asked Answered
C

3

21

I tried googling this but only objected oriented languages pop up as results.

From my understanding a shallow copy is copying certain members of a struct.

so lets say a struct is

typedef struct node
{
    char **ok;
    int hi;
    int yep;
    struct node *next;
}node_t

copying the char** would be a shallow copy

but copying the whole linked list would be a deep copy?

Do I have the right idea or am I way off? Thanks.

Chari answered 7/3, 2013 at 17:49 Comment(0)
C
35

No. A shallow copy in this particular context means that you copy "references" (pointers, whatever) to objects, and the backing store of these references or pointers is identical, it's the very same object at the same memory location.

A deep copy, in contrast, means that you copy an entire object (struct). If it has members that can be copied shallow or deep, you also make a deep copy of them. Consider the following example:

typedef struct {
    char *name;
    int value;
} Node;

Node n1, n2, n3;

char name[] = "This is the name";

n1 = (Node){ name, 1337 };
n2 = n1; // Shallow copy, n2.name points to the same string as n1.name

n3.value = n1.value;
n3.name = strdup(n1.name); // Deep copy - n3.name is identical to n1.name regarding
                           // its *contents* only, but it's not anymore the same pointer
Chaudfroid answered 7/3, 2013 at 17:57 Comment(0)
B
1

From my understanding there is no actual "Shallow" copy or "Deep copy" inbuilt in C.

Some answer you may find are right but misleading if you think in an OOP perspective

In C, there is only one inbuilt copy technique when using the '=' operator, Data copy

C stores the metadata of a structure in the RAM and makes sure that once a struct is created, it's size will not change and the variables can be accessed from specific parts of the allocated memory

When you use the '=' operator, it only copies the data stored in the structure but by bit into another structure since they have same size.

Statically allocated variables and arrays in a struct have a fixed size and are stored completely within the struct's allocated memory. Dynamically allocated variables are all pointers. Pointers variables are statically allocated memory equivalent to an unsigned long int.

When you have a pointer in a struct, it only stored the address, the memory it points to, aka, the dynamically allocated location, the struct doesn't actually have any information that the pointer is pointing to a memory. It is the OS and the Complier that keeps track of dynamically allocated memory.

For example:

#include <stdio.h>
#include<stdlib.h> 
struct Foo
{
    int value_1;
    int *value_2;
    int value_3[3];
}S1,S2;

 
void print(struct Foo S)
{
    printf("%d,%d,%d,%d,%d\n",S.value_1,*(S.value_2),S.value_3[0],S.value_3[1],S.value_3[2]);
}
int main()
{
    S1.value_1=43;
    S1.value_2=(int*)malloc(sizeof(int));
    *(S1.value_2)=55;
    S1.value_3[0]=101;
    S1.value_3[1]=102;
    S1.value_3[2]=103;
    printf("S1:");
    print(S1);
    S2=S1;
    printf("S2:");
    print(S2);
    S1.value_1=4300;
    *(S1.value_2)=5500;
    S1.value_3[0]=10100;
    S1.value_3[1]=10200;
    S1.value_3[2]=10300;
    printf("\nAfter Altering\n");
    printf("S1:");
    print(S1);
    printf("S2:");
    print(S2);
    return 0;
}
 

Output:

S1:43,55,101,102,103
S2:43,55,101,102,103

After Altering
S1:4300,5500,10100,10200,10300
S2:43,5500,101,102,103

In short, copying in C has 2 behaviours:

  • For dynamically allocated variables, aka pointers, Shallow Copy is used
  • For statically allocated Variables or arrays, Deep copy is used

Additionally, if you were to make a pointer to a structure variable(not newly allocated), as long as the memory is within scope, it would act as a like a reference, any change made using either the normal variable or the structure pointer would result in both reflecting the same.

int a=20;
Foo S1,*S2;
S2=&S1;
S1.value1=10;
S1.value2=&a;
S1.value3[0]=101;
S1.value3[1]=102;
S1.value3[2]=103;
S2->value1=15;

In the above case, it doesn't matter which one we try to manipulate the values, since both affect the same physical memory

When you copy pointers as pointers/addresses, a shallow copy occurs When you copy the value from a pointer to another variable/pointer , it behaves like copying between 2 non-pointers

Bosk answered 20/4, 2023 at 17:44 Comment(2)
This is totally misleading. Add a global int (static), and make s1.value2 point to its address. The result will be exactly the same. Make S1 a pointer to a Foo struct, and make it point to a malloc'ed memory (of course fix the syntax related to S1 in the code, with ->, S2 = *S1, etc...). The result will be exactly the same.Afb
@Afb I missed out an important assumption there, thank you for pointing it out. In the Post, i am referring to the copying of non-pointer Structure variables when using '=' . I did not include the scenario where a pointer points to an existing memory of a seperate variable.Bosk
K
-2

The copy constructor is used to initialize the new object with the previously created object of the same class. By default compiler wrote a shallow copy. Shallow copy works fine when dynamic memory allocation is not involved because when dynamic memory allocation is involved then both objects will points towards the same memory location in a heap, Therefore to remove this problem we wrote deep copy so both objects have their own copy of attributes in a memory. In order to read the details with complete examples and explanations you could see the portion of this article about difference between Shallow and Deep copy constructors.

Kilby answered 8/2, 2014 at 13:22 Comment(2)
The post is specifically about the C language. Constructors and copy constructors are exclusive C++ (and oop) features. Your answer, though explained well, can be totally misleading in this context. I am sorry but it deserves downvotesConvulse
Agree with @kyriakosSt, Post is totally irrelevant to what is originally asked by ShadyBears.Vaunting

© 2022 - 2024 — McMap. All rights reserved.