title: Valgrind message : Address XXX is in a r-x mapped file <fielpath> segment
body: <p>I am learning C for malloc and free heap memory related to self-defined structure.</p>
  
  <h2>The problem I met</h2>
  
  <p>For below code I constantly got <code>segment fault</code>.
  Using <code>valgrind</code> to analysios showed : <code>==12999==  Address 0x108b4b is in a r-x mapped file &lt;folder_path&gt; segment
  ==12999==</code></p>
  
  <p>full output : </p>
  
  <pre><code>Name : Amy 
  Date of Birth: 1989 9 21
  Name : echo 
  Date of Birth: 1989 9 21
  Name : echo 
  Date of Birth: 1989 9 21
  Name : echo Address 0x5580be70e270
  Date of Birth: 1989 9 21
  Their address : 0x5580be70e260 0x5580be70e264 0x5580be70e268
  Name : echo Address 0x5580be70e270
  Date of Birth: 1989 9 21
  Their address : 0x5580be70e260 0x5580be70e264 0x5580be70e268
  free p-&gt;name 
  Segmentation fault (core dumped)
  
  </code></pre>
  
  <h2>The analysis I did</h2>
  
  <p>I use <code>valgrind</code> to try to find where results this:
  <code>valgrind --tool=memcheck --leak-check=full ./person2</code>
  The output is shown as :</p>
  
  <pre><code>Their address : 0x522d040 0x522d044 0x522d048
  Name : echo Address 0x522d050
  Date of Birth: 1989 9 21
  Their address : 0x522d040 0x522d044 0x522d048
  free p-&gt;name 
  ==12999== Invalid free() / delete / delete[] / realloc()
  ==12999==    at 0x4C30D3B: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
  ==12999==    by 0x108894: Person_destruct (person2.c:33)
  ==12999==    by 0x108A2F: main (person2.c:74)
  ==12999==  Address 0x108b4b is in a r-x mapped file /folder/path segment
  ==12999== 
  freed p-&gt;name 
  free p 
  freed p 
  ==12999== 
  ==12999== HEAP SUMMARY:
  ==12999==     in use at exit: 4 bytes in 1 blocks
  ==12999==   total heap usage: 3 allocs, 3 frees, 1,052 bytes allocated
  ==12999== 
  ==12999== 4 bytes in 1 blocks are definitely lost in loss record 1 of 1
  ==12999==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
  ==12999==    by 0x108817: Person_construct (person2.c:16)
  ==12999==    by 0x1089CC: main (person2.c:64)
  ==12999== 
  ==12999== LEAK SUMMARY:
  ==12999==    definitely lost: 4 bytes in 1 blocks
  ==12999==    indirectly lost: 0 bytes in 0 blocks
  ==12999==      possibly lost: 0 bytes in 0 blocks
  ==12999==    still reachable: 0 bytes in 0 blocks
  ==12999==         suppressed: 0 bytes in 0 blocks
  ==12999== 
  ==12999== For counts of detected and suppressed errors, rerun with: -v
  ==12999== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
  
  </code></pre>
  
  <p>What I understand is that <code>*p3</code> points to the exact same memory piece as <code>p1</code> (which proved by <code>Person_address_print()</code>, thus I only explicitly  destruct <code>p1</code> to avoid twice destruct the same heap memory.)
  I also tried to let <code>p3-&gt;name = "ada";</code> to ensure the allocated string is still within the previous length (3) or explicitly set <code>p3 == NULL</code> before calling <code>Person_destruct(p1)</code>; the same segment fault error occurs :(</p>
  
  <h2>The code</h2>
  
  <p>Here is the code. The code basically does:
  a. self-defined a structure <code>Person</code>
  b. (in <code>main</code>)construct objects for <code>Person</code>, destruct them and print related attributes.</p>
  
  <pre><code>//  person.h
  #ifndef PERSON_H
  #define PERSON_H
  typedef struct
  {
      int year;
      int month;
      int date;
      char * name; // name is a ponter b/c name length is unknown
  } Person;
  Person * Person_construct(int y, int m, int d, char * n);
  void Person_destruct(Person *p);
  void Person_print(Person * p);
  #endif
  </code></pre>
  
  <pre><code>#include "person.h"
  #include &lt;stdio.h&gt;
  #include &lt;string.h&gt;
  #include &lt;stdlib.h&gt;
  Person *Person_construct(int y, int m, int d, char *n)
  {
      Person *p = NULL;
      p = malloc(sizeof (Person));
      if (p == NULL) // malloc failed
      {
          return NULL;
      }
      p-&gt;year= y;
      p-&gt;month = m;
      p-&gt;date = d;
      p-&gt;name = malloc(sizeof(char) * (strlen(n) + 1));
      // + 1 for the neding char '\0'
      if ((p-&gt;name) == NULL)// malloc failed, just return
      {
          free(p); 
          return NULL;
      }
      strcpy(p-&gt;name, n);
      return p;
  }
  
  void Person_destruct(Person *p)
  {
      // p-&gt;name must be freed befoer p is freed
      if (p-&gt;name != NULL)
      {
          printf("free p-&gt;name \n");
          free(p-&gt;name);
          printf("freed p-&gt;name \n");
      }
  
      if (p != NULL)
      {
          printf("free p \n");
          free(p);
          printf("freed p \n");
      }
  }
  
  void Person_print(Person *p)
  {
      printf("Name : %s \n", p-&gt;name);
      printf("Date of Birth: %d %d %d\n", 
          p-&gt;year, p-&gt;month, p-&gt;date);
  }
  
  
  void Person_address_print(Person *p)
  {
      printf("Name : %s Address %p\n", p-&gt;name, &amp;(p-&gt;name));
      printf("Date of Birth: %d %d %d\n", 
          p-&gt;year, p-&gt;month, p-&gt;date);
      printf("Their address : %p %p %p\n", 
          &amp;(p-&gt;year), &amp;(p-&gt;month), &amp;(p-&gt;date));
  }
  
  int main(int argc, char ** argv)
  {
      Person * p1 = Person_construct(1989,9, 21, "Amy");
      Person_print(p1);
  
      Person * p3 = p1;
      p3-&gt;name = "echo";
      Person_print(p3);
      Person_print(p1); // p1's name should have changed to "echo".
      Person_address_print(p1);
      Person_address_print(p3);
  
  
      Person_destruct(p1);
      // p3 is pointing to the same memory of p1, should not destruct(p3)
  
      return EXIT_SUCCESS;
  
  }
  
  </code></pre>
  
  <h2>The environment I am running</h2>
  
  <p>gcc (Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0</p>
  
  <p>valgrind-3.13.0</p>
  
  <p>Thanks so much for any clue!</p>