title: Valgrind invalid write of size 8
body: <p>I'm experimenting with C structs and I've come up with a <code>invalid write of size 8</code> followed by <code>invalid read of size 8</code> messages from valgrind.</p>
  
  <p>My code is only looping through arguments (if <code>argc &gt; 1</code>) and for each filename, it scans for a <code>string</code> and <code>unsigned int</code> indicating name and age(struct player).</p>
  
  <p>This is all the code I've got so far:</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;stdlib.h&gt;
  #include &lt;string.h&gt;
  
  struct player {
    char name[20];
    unsigned int age;
  };
  
  struct player *player_new_from_stream(FILE * stream){
    struct player *new_player = (struct player*) malloc(sizeof(struct player));
    char *p_name = malloc(20);
    char *p_age = malloc(20);
  
    if (stream != stdin){
      if (fgets(p_name, 20, stream) != NULL){
        char *p = strrchr(p_name, '\n');
        if (p)
          *p = '\0';
        strcpy(new_player-&gt;name, p_name);
      }
      if (fgets(p_age, 20, stream) != NULL)
        new_player-&gt;age = atoi(p_age);
    }
    else {
      printf("enter name and age for a player\n");
      gets(p_name);
      gets(p_age);
      strcpy(new_player-&gt;name, p_name);
      new_player-&gt;age = atoi(p_age);
    }
  
    free(p_name);
    free(p_age);
    return new_player;
  }
  
  void player_inspect(struct player plyr, char* prefix){
    printf("[%s] name: %s\n", prefix, plyr.name);
    printf("[%s] age : %d\n", prefix, plyr.age);
  }
  
  int main(int argc, char* argv[]){
    FILE * stream;
    char* argument;
    // below: trying to allocate (argc - 1) pointers
    // valgrind's --show-origins=yes points here for both errors
    struct player **players = malloc(sizeof(int) * (argc - 1)); 
    int i = 1;
    for (; i &lt; argc; i++){
      argument = argv[i];
      if (strcmp("-", argument) != 0){
        if ((stream = fopen(argument, "r")) == NULL) perror("Error opening file");
        else {
          // the next line emits Invalid write of size 8 in valgrind
          players[i-1] = player_new_from_stream(stream);
          fclose(stream);
        }
      } else {
        players[i-1] = player_new_from_stream(stdin);
      }
    }
  
    i = 0;
    char buffer[15];
    for (; i &lt; argc - 1; i++){
      sprintf(buffer, "%d", i);
      // the next line emits Invalid read of size 8
      player_inspect(*(players[i]), buffer);
      free(players[i]);
    }
  
    free(players);
    return 0;
  }
  </code></pre>
  
  <p>What is wrong here? I want to return a pointer to <code>struct player</code> from <code>player_new_from_stream</code> and pack this pointer to array <code>players</code> in <code>main()</code>.</p>