Is a shallow copy sufficient for structures with char []?

I have a structure containing arrays of characters without any other member functions. I perform an assignment operation between two instances of these structures. If I'm not mistaken, he makes a shallow copy. In this case, is the bagged copy safe?

I tried this in C ++ and worked, but I just wanted to confirm if this behavior is safe.

+4
source share
2 answers

If by “shallow copy” you mean that after assigning a struct containing an array, the array will point to the original data of the struct , and then: it cannot. Each element of the array must be copied to a new struct . A shallow copy appears in the picture if your structure has pointers. If this is not the case, you cannot make a shallow copy.

When you assign a value to a struct containing an array for some value, it cannot execute a shallow copy, as that means assigning to an array, which is illegal. So, the only copy you get is a deep copy.

Consider:

 #include <stdio.h> struct data { char message[6]; }; int main(void) { struct data d1 = { "Hello" }; struct data d2 = d1; /* struct assignment, (almost) equivalent to memcpy(&d2, &d1, sizeof d2) */ /* Note that it illegal to say d2.message = d1.message */ d2.message[0] = 'h'; printf("%s\n", d1.message); printf("%s\n", d2.message); return 0; } 

The above text will print:

 Hello hello 

If, on the other hand, your struct had a pointer, the struct assignment will only copy pointers that are a “shallow copy”:

 #include <stdio.h> #include <stdlib.h> #include <string.h> struct data { char *message; }; int main(void) { struct data d1, d2; char *str = malloc(6); if (str == NULL) { return 1; } strcpy(str, "Hello"); d1.message = str; d2 = d1; d2.message[0] = 'h'; printf("%s\n", d1.message); printf("%s\n", d2.message); free(str); return 0; } 

The above text will print:

 Hello hello 

In general, a given struct T d1, d2; d2 = d1; equivalent to memcpy(&d2, &d1, sizeof d2); but if the structure has padding, it may or may not be copied.

Edit: In C, you cannot assign arrays . Given:

 int data[10] = { 0 }; int data_copy[10]; data_copy = data; 

is illegal. So, as I said above, if you have an array in a struct , the purpose of the structure is to copy the data elements in the array. You do not get a shallow copy in this case: it makes no sense to apply the term "shallow copy" to this case.

+9
source

Destination structs performs membership assignment, and for arrays, this means assigning each element. (And this is done recursively for arrays with many dimensions, which are actually just arrays of arrays.)

You are right that it makes a shallow copy even on arrays. (I assume that you did not overload op = with C ++, if you overload it, you can do whatever you want.)

Remember that a shallow copy means copying the value of something, while a deep copy means copying the value to which something points or refers. An array value is every element in it.

The difference between shallow and deep is most significant when you have a type that does an indirect action, such as a pointer. I find my answer the most useful way to look at this problem, but you can also say that the “shallow” and “deep” don't even apply to other types, and they are just “copied”.

 struct S { int n; int* p; int a[2]; int* ap[2]; int xy[2][2]; }; void f() { S c, d; c = d; // equivalent to: cn = dn; cp = dp; ca[0] = da[0]; // S::a is similar to your situation, only using ca[1] = da[1]; // int instead of char. c.ap[0] = d.ap[0]; c.ap[1] = d.ap[1]; c.xy[0][0] = d.xy[0][0]; c.xy[0][1] = d.xy[0][1]; c.xy[1][0] = d.xy[1][0]; c.xy[1][1] = d.xy[1][1]; } 

The fact that I used int above does not change anything from semantics, it works the same for char arrays, copying each char. This is S :: situation in my code.

Note that p and ap are copied shallowly (like every other element). If these pointers “own” the memory they are pointing to, then this may be unsafe. ("Safe" in your question is vague, and actually depends on what you expect and how you handle things.)

For an interesting twist, consider boost :: shared_ptr and other C ++ smart pointers. They can be copied shallow, although a deep copy is possible, and it can still be safe.

+2
source

Source: https://habr.com/ru/post/1300941/


All Articles