0

How does C handle copying structs (not pointer to structs) with the assignment operator. I have a sample program below demonstrating my question.

struct s {
  char string[20];
};

void main() {
  struct s var1, var2;
  strcpy(var1.string, "hello");
  printf("var1: %s\n", var1.string);
  printf("var2: %s\n", var2.string);
  var2 = var1;
  printf("var1: %s\n", var1.string);
  printf("var2: %s\n\n", var2.string);
  strcpy(var2.string, "goodbye");
  printf("var1: %s\n", var1.string);
  printf("var2: %s\n", var2.string);
}

The output I expect is first "var1: hello var2:" since var2.string is nothing.

The second block should be "var1: hello var2: hello", since var1 and var2 are the same.

The third block should be "var1: goodbye var2: goodbye", since var1 and var2 should be the same memory location.

What I get for the third block, though, is "var1: hello var2: goodbye". So it looks like the line var2 = var1 sets all of the attributes of var2 to the attributes of var1 automatically. Is this what C does instead of simply decomposing them to locations in memory?

cdhowie
  • 158,093
  • 24
  • 286
  • 300
  • 1
    Your first `printf("var2: %s\n", var2.string);` causes undefined behavior, since you have not initialized `var2.string` to anything. You're lucky this doesn't cause the program to crash. – cdhowie Sep 26 '13 at 18:53

2 Answers2

4

The third block should be "var1: goodbye var2: goodbye", since var1 and var2 should be the same memory location.

No, var1 and var2 exist in different memory locations.

Assigning an instance of one struct to another blits (copies) the memory region used by the source struct onto that of the destination struct. After this operation they are still independent objects in memory, you've simply copied the value of all of the members from one to the other.

Future changes to one object will not affect the other, unless of course you copy one onto the other again.

cdhowie
  • 158,093
  • 24
  • 286
  • 300
  • So does C treat structs the same as primitives? – Billy Hardy Sep 26 '13 at 19:12
  • 1
    @BillyHardy I don't know enough about the spec to say for sure that it treats them "exactly the same" but it does treat them as values (as opposed to references). – cdhowie Sep 26 '13 at 19:13
  • Since it blits the memory region, could you do `var1 ^= var2` and xor the bits of both regions? – Billy Hardy Sep 26 '13 at 22:15
  • @BillyHardy The `^` operator is not defined for structs. In C++ you may be able to overload it, but in both cases you'd have to do the xor operation yourself. – cdhowie Sep 26 '13 at 22:49
0

Here you are dealing with actual separate memory locations. When you assign var2 = var1, , this does a deep copy of the structure and not a shallow copy as would be the case if you were dealing with pointers instead.

Freddie
  • 871
  • 6
  • 10
  • 1
    It's actually somewhere between deep and shallow. For example, if the struct contains pointers then the pointers are copied; the target object of the pointer is not copied into a new allocation. – cdhowie Sep 26 '13 at 19:03