I have been reading a number of questions on this site about how to duplicate structs in C. I've been playing around with some code, trying to understand the differences between 'shallow' copying (where the new struct is simply assigned a pointer to the memory address of the first struct) and 'deep' copying (where the data is copied member-by-member into a new chunk of memory).
I created the following code, assuming that it would show the 'shallow' copying behavior:
#include <stdio.h>
struct tester
{
int blob;
int glob;
char* doob[10];
};
int main (void)
{
//initializing first structure
struct tester yoob;
yoob.blob = 1;
yoob.glob = 2;
*yoob.doob = "wenises";
//initializing second structure without filling members
struct tester newyoob;
newyoob = yoob;
//assumed this line would simply copy the address pointed to by 'yoob'
//printing values to show that they are the same initially
printf("Before modifying:\n");
printf("yoob blob: %i\n", yoob.blob);
printf("newyoob blob: %i\n", newyoob.blob);
//modifying 'blob' in second structure. Assumed this would be mirrored by first struct
newyoob.blob = 3;
//printing new int values
printf("\nAfter modifying:\n");
printf("yoob blob: %i\n", yoob.blob);
printf("newyoob blob: %i\n", newyoob.blob);
//printing memory addresses
printf("\nStruct memory addresses:\n");
printf("yoob address: %p\n", &yoob);
printf("newyoob address: %p\n", &newyoob);
}
Output on running:
Before modifying:
yoob blob: 1
newyoob blob: 1
After modifying:
yoob blob: 1
newyoob blob: 3
Struct memory addresses:
yoob address: 0x7fff3cd98d08
newyoob address: 0x7fff3cd98cb0
Is this code create a deep copy, as it appears, or am I misunderstanding what's happening here?
The shallow vs. deep copy problem is only relevant to pointers. Given a type struct foo
:
struct foo a = /* initialize */;
struct foo b = a;
All the values in a
are copied to b
. They are not the same variable.
However, with pointers:
struct foo *p = calloc(1, sizeof *p);
struct foo *q = p;
q
now points to the same memory as p
; no copying has taken place (and you run the risk of a dangling pointer once one gets free
d). This is a pointer alias. In order to do a shallow copy, one would do:
struct foo *p = calloc(1, sizeof *p);
/* assign to p's fields... */
struct foo *q = calloc(1, sizeof *q);
*q = *p;
Now q
has the same field values as p
but points to a different block of memory.
A deep copy requires additional effort; any pointers in the structure must be traversed and have their contents copied as well. See this post for a good explanation.
When you use newyoob = yoob;
the compiler create code to copy the structure for you.
An important note about the copying: It's a shallow. That means if you have e.g. a structure containing pointers, it's only the actual pointers that will be copied and not what they point to, so after the copy you will have two pointers pointing to the same memory.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With