title: memcpy of structure having pointers as members in C
body: <p>I have a structure with some pointers as members and I am trying to do memcpy and I have been suggested that I should not use memcpy in this case as memcpy do a shallow copy (meaning it copies pointers) rather deep copy (meaning copying what pointers point to).</p>
  
  <p>But I am not sure why it is not making any difference in the following program:
  Please have a look at code and output and please explain why it is not a shallow copy in this case?</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;malloc.h&gt;
  #include &lt;string.h&gt;
  
  struct student {
      char *username;
      char *id;
      int roll;
  };
  
  void print_struct(struct student *);
  void print_struct_addr(struct student *);
  void changeme(struct student *);
  
  int main (void) {
      struct student *student1;
      char *name = "ram";
      char *id = "200ABCD";
      int roll = 34;
  
      student1 = (struct student *)malloc(sizeof(struct student));
      student1-&gt;username = name; 
      student1-&gt;id = id;
      student1-&gt;roll = roll; 
      print_struct_addr(student1);
      print_struct(student1);
      changeme(student1);
      print_struct(student1);
      print_struct_addr(student1);
      return 0;
  }
  
  void print_struct(struct student *s) {
      printf("Name: %s\n", s-&gt;username);
      printf("Id: %s\n", s-&gt;id); 
      printf("R.No: %d\n", s-&gt;roll);
      return; 
  }
  
  void print_struct_addr(struct student *s) {
      printf("Addr(Name): %x\n", &amp;s-&gt;username);
      printf("Addr(Id): %x\n", &amp;s-&gt;id);
      printf("Addr(R.No): %x\n", &amp;s-&gt;roll);
      return;
  }
  
  void changeme(struct student *s) {
      struct student *student2;
      student2-&gt;username = "someone";
      student2-&gt;id = "200EFGH";
      student2-&gt;roll = 35;
      print_struct_addr(student2);
      memcpy(s, student2, sizeof(struct student));
      student2-&gt;username = "somebodyelse";
      return;
  }
  </code></pre>
  
  <p>output:</p>
  
  <pre><code>Addr(Name): 9b72008
  Addr(Id): 9b7200c
  Addr(R.No): 9b72010
  Name: ram
  Id: 200ABCD
  R.No: 34
  Addr(Name): fa163c
  Addr(Id): fa1640
  Addr(R.No): fa1644
  Name: someone
  Id: 200EFGH
  R.No: 35
  Addr(Name): 9b72008
  Addr(Id): 9b7200c
  Addr(R.No): 9b72010
  </code></pre>
  
  <p>If memcpy does a shallow copy, how come student1->username is NOT "somebodyelse".</p>
  
  <p>Please explain in which scenario, this code can create problem, I want student2 information in student1 after changeme() call in main() and should be able to use this modified student1 data afterwards.</p>
  
  <p>I have been suggested to NOT to use memcpy() here, but it seems to be working fine.</p>
  
  <p>Thanks</p>
  
  <p>This is the modified code: But still I dont see concept of shallow copy here:</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;malloc.h&gt;
  #include &lt;string.h&gt;
  
  struct student {
      char *username;
      char *id;
      int roll;
  };
  
  void print_struct(struct student *);
  void print_struct_addr(struct student *);
  void changeme(struct student *);
  
  int main (void) {
      struct student *student1;
      char *name = "ram";
      char *id = "200ABCD";
      int roll = 34;
  
      student1 = malloc(sizeof(*student1));
      student1-&gt;username = name; 
      student1-&gt;id = id;
      student1-&gt;roll = roll; 
      print_struct_addr(student1);
      print_struct(student1);
      changeme(student1);
      print_struct(student1);
      print_struct_addr(student1);
      return 0;
  }
  
  void print_struct(struct student *s) {
      printf("Name: %s\n", s-&gt;username);
      printf("Id: %s\n", s-&gt;id); 
      printf("R.No: %d\n", s-&gt;roll);
      return; 
  }
  
  void print_struct_addr(struct student *s) {
      printf("Addr(Name): %x\n", &amp;s-&gt;username);
      printf("Addr(Id): %x\n", &amp;s-&gt;id);
      printf("Addr(R.No): %x\n", &amp;s-&gt;roll);
      return;
  }
  
  void changeme(struct student *s) {
      struct student *student2;
      student2 = malloc(sizeof(*s));
      student2-&gt;username = strdup("someone");
      student2-&gt;id = strdup("200EFGH");
      student2-&gt;roll = 35;
      print_struct_addr(student2);
      memcpy(s, student2, sizeof(struct student));
      student2-&gt;username = strdup("somebodyelse");
      free(student2);
      return;
  }
  </code></pre>