title: How to properly write an array of structs to a pipe in C
body: <p>I have a hard time figuring out how to pass an array of structs with strings in them through a pipe to a child process.<br />
  I created two demos to show my problem.<br />
  <code>demo_int.c</code></p>
  <pre class="lang-c prettyprint-override"><code>#include &lt;stdlib.h&gt;
  #include &lt;stdio.h&gt;
  #include &lt;unistd.h&gt;
  #include &lt;sys/wait.h&gt;
  
  int main()
  {
      pid_t child;
      int pfd[2];
      if (pipe(pfd) == -1)
      {
          exit(1);
      }
  
      child = fork();
      if (child &lt; 0)
      {
          exit(1);
      }
  
      if (child == 0)
      {
          close(pfd[1]);
          int *arr = malloc(10 * sizeof(int));
          if (arr == NULL)
          {
              exit(1);
          }
          read(pfd[0], arr, 10 * sizeof(int));
          close(pfd[0]);
          printf(&quot;child process read:\n&quot;);
          for (int i = 0; i &lt; 10; ++i)
          {
              printf(&quot;%d\n&quot;, arr[i]);
          }
          free(arr);
          exit(0);
      }
      else
      {
          int *arr = malloc(10 * sizeof(int));
          if (arr == NULL)
          {
              exit(1);
          }
          for (int i = 0; i &lt; 10; ++i)
          {
              arr[i] = i;
          }
  
          printf(&quot;array to be written:\n&quot;);
          for (int i = 0; i &lt; 10; ++i)
          {
              printf(&quot;%d\n&quot;, arr[i]);
          }
  
          close(pfd[0]);
          write(pfd[1], arr, 10 * sizeof(int));
          close(pfd[1]);
          free(arr);
          printf(&quot;parent process done\n&quot;);
          wait(NULL);
      }
  }
  </code></pre>
  <p>I created this, so I can be sure that the problem is not with the &quot;dynamic array&quot; part, but with the &quot;structs&quot; part, and maybe more specifically the &quot;string in a struct&quot; part.<br />
  This produces the expected result:</p>
  <pre><code>array to be written:
  0
  1
  2
  3
  4
  5
  6
  7
  8
  9
  parent process done
  child process read:
  0
  1
  2
  3
  4
  5
  6
  7
  8
  9
  </code></pre>
  <p>With <code>valgrind</code> reporting no errors or leaks.<br />
  However when I try the same with the problematic structs:</p>
  <p><code>demo_person.c</code></p>
  <pre class="lang-c prettyprint-override"><code>#include &lt;stdlib.h&gt;
  #include &lt;stdio.h&gt;
  #include &lt;string.h&gt;
  #include &lt;unistd.h&gt;
  #include &lt;sys/wait.h&gt;
  
  typedef struct Person
  {
      char *name;
      int age;
  } Person;
  
  int main()
  {
      pid_t child;
      int pfd[2];
      if (pipe(pfd) == -1)
      {
          exit(1);
      }
  
      child = fork();
      if (child &lt; 0)
      {
          exit(1);
      }
  
      if (child == 0)
      {
          close(pfd[1]);
          Person *arr = malloc(10 * sizeof(Person));
          if (arr == NULL)
          {
              exit(1);
          }
          read(pfd[0], arr, 10 * sizeof(Person));
          close(pfd[0]);
          printf(&quot;child process read:\n&quot;);
          for (int i = 0; i &lt; 10; ++i)
          {
              printf(&quot;%s %d\n&quot;, arr[i].name, arr[i].age);
          }
  
          for (int i = 0; i &lt; 10; ++i)
          {
              free(arr[i].name);
          }
          free(arr);
          exit(0);
      }
      else
      {
          Person *arr = malloc(10 * sizeof(Person));
          if (arr == NULL)
          {
              exit(1);
          }
          for (int i = 0; i &lt; 10; ++i)
          {
              char *name = malloc(8 * sizeof(char));
              if (name == NULL)
              {
                  exit(1);
              }
              sprintf(name, &quot;%s%d&quot;, &quot;Person&quot;, i);
              arr[i].name = malloc(8 * sizeof(char));
              if (arr[i].name == NULL)
              {
                  exit(1);
              }
              strcpy(arr[i].name, name);
              arr[i].age = i;
              free(name);
          }
  
          printf(&quot;array to be written:\n&quot;);
          for (int i = 0; i &lt; 10; ++i)
          {
              printf(&quot;%s %d\n&quot;, arr[i].name, arr[i].age);
          }
  
          close(pfd[0]);
          write(pfd[1], arr, 10 * sizeof(Person));
          close(pfd[1]);
  
          for (int i = 0; i &lt; 10; ++i)
          {
              free(arr[i].name);
          }
          free(arr);
          printf(&quot;parent process done\n&quot;);
          wait(NULL);
      }
  }
  </code></pre>
  <p>The output is:</p>
  <pre><code>array to be written:
  Person0 0
  Person1 1
  Person2 2
  Person3 3
  Person4 4
  Person5 5
  Person6 6
  Person7 7
  Person8 8
  Person9 9
  parent process done
  child process read:
   0
   1
   2
   3
   4
   5
   6
   7
   8
   9
  free(): invalid pointer
  </code></pre>
  <p>With <code>valgrind</code> reporting loads of errors (as expected after this output).<br />
  I found similiar looking questions, but none of the answers seemed to help.</p>
  <p><strong>EDIT:</strong></p>
  <p>Thanks to the answer I now understand that the problem is with the dynamically allocated string and only the mallocing process can access it, but the real program in which I encountered this problem has been populated (kind of) like this, as in it already uses these dinamically allocated strings.<br />
  Is there a way to pass the strings like this, or do I have to solve it somehow with new char[N] arrays?</p>