title: Possible memory leak valgrind c
body: <p>I have just started using valgrind and am not very good with pointers so what I essentially want to do is pass the snake_thread s[1] variable as reference to all the functions so that I don't have to free the memory in each of the functions individually.</p>
  <pre><code>==20== HEAP SUMMARY:
  ==20==     in use at exit: 17,704 bytes in 65 blocks
  ==20==   total heap usage: 75 allocs, 10 frees, 32,646 bytes allocated
  ==20==
  ==20== 56 bytes in 1 blocks are still reachable in loss record 1 of 8
  ==20==    at 0x483DD99: calloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
  ==20==    by 0x10A068: initialize (snake_map_test.c:249)
  ==20==    by 0x1098C1: main (snake_map_test.c:126)
  ==20==
  ==20== 56 bytes in 1 blocks are still reachable in loss record 2 of 8
  ==20==    at 0x483DD99: calloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
  ==20==    by 0x10A089: initialize (snake_map_test.c:250)
  ==20==    by 0x1098C1: main (snake_map_test.c:126)
  ==20==
  ==20== 160 bytes in 1 blocks are still reachable in loss record 3 of 8
  ==20==    at 0x483DD99: calloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
  ==20==    by 0x10B992: Read_args (snake_map_test.c:571)
  ==20==    by 0x109887: main (snake_map_test.c:122)
  ==20==
  ==20== 272 bytes in 1 blocks are possibly lost in loss record 4 of 8
  ==20==    at 0x483DD99: calloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
  ==20==    by 0x40149CA: allocate_dtv (dl-tls.c:286)
  ==20==    by 0x40149CA: _dl_allocate_tls (dl-tls.c:532)
  ==20==    by 0x485C322: allocate_stack (allocatestack.c:622)
  ==20==    by 0x485C322: pthread_create@@GLIBC_2.2.5 (pthread_create.c:660)
  ==20==    by 0x10972E: main (snake_map_test.c:111)
  ==20==
  ==20== 272 bytes in 1 blocks are possibly lost in loss record 5 of 8
  ==20==    at 0x483DD99: calloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
  ==20==    by 0x40149CA: allocate_dtv (dl-tls.c:286)
  ==20==    by 0x40149CA: _dl_allocate_tls (dl-tls.c:532)
  ==20==    by 0x485C322: allocate_stack (allocatestack.c:622)
  ==20==    by 0x485C322: pthread_create@@GLIBC_2.2.5 (pthread_create.c:660)
  ==20==    by 0x1098F8: main (snake_map_test.c:130)
  ==20==
  ==20== 400 bytes in 20 blocks are still reachable in loss record 6 of 8
  ==20==    at 0x483DD99: calloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
  ==20==    by 0x10BA1C: Read_args (snake_map_test.c:575)
  ==20==    by 0x109887: main (snake_map_test.c:122)
  ==20==
  ==20== 5,880 bytes in 1 blocks are still reachable in loss record 7 of 8
  ==20==    at 0x483DD99: calloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
  ==20==    by 0x10A048: initialize (snake_map_test.c:248)
  ==20==    by 0x1098C1: main (snake_map_test.c:126)
  ==20==
  ==20== 10,608 bytes in 39 blocks are possibly lost in loss record 8 of 8
  ==20==    at 0x483DD99: calloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
  ==20==    by 0x40149CA: allocate_dtv (dl-tls.c:286)
  ==20==    by 0x40149CA: _dl_allocate_tls (dl-tls.c:532)
  ==20==    by 0x485C322: allocate_stack (allocatestack.c:622)
  ==20==    by 0x485C322: pthread_create@@GLIBC_2.2.5 (pthread_create.c:660)
  ==20==    by 0x109DD4: run_snake_threads (snake_map_test.c:217)
  ==20==    by 0x485B608: start_thread (pthread_create.c:477)
  ==20==    by 0x4997292: clone (clone.S:95)
  ==20==
  ==20== LEAK SUMMARY:
  ==20==    definitely lost: 0 bytes in 0 blocks
  ==20==    indirectly lost: 0 bytes in 0 blocks
  ==20==      possibly lost: 11,152 bytes in 41 blocks
  ==20==    still reachable: 6,552 bytes in 24 blocks
  ==20==         suppressed: 0 bytes in 0 blocks
  ==20==
  ==20== Use --track-origins=yes to see where uninitialised values come from
  ==20== For lists of detected and suppressed errors, rerun with: -s
  ==20== ERROR SUMMARY: 6 errors from 6 contexts (suppressed: 0 from 0)
  </code></pre>
  <p>These are the relevant functions</p>
  <pre><code>void* update(void* arg)
  {
      snake* s=(snake*)arg;
      
      if (GAMEOVER == false)
      {
          if (s-&gt;dir == LEFT)
              s-&gt;headX--;
          else if (s-&gt;dir == RIGHT)
              s-&gt;headX++;
          else if (s-&gt;dir == DOWN)
              s-&gt;headY++;
          else if (s-&gt;dir == UP)
              s-&gt;headY--;
  
      }
     
      pthread_exit(0);
  }
  </code></pre>
  <pre><code>void* run_snake_threads(void* arg)
  {
      snake_thread* s = (snake_thread*)arg;
      while (GAMEOVER == false)
      {
          pthread_testcancel(); //cancellation point
          map_init(s,s-&gt;food);
          if(print_flag==1)
              print(s-&gt;map);
          for (int i = 0; i &lt; s-&gt;info-&gt;size; i++)
          {
              input(s-&gt;snake_list, &amp;s-&gt;snake_list[i], s-&gt;map, s-&gt;info,&amp;s-&gt;food[i]);
              
              int err = pthread_create(&amp;(s-&gt;pid[i]), NULL, update, (void*)&amp;(s-&gt;snake_list[i]));
              if (err != 0) ERR(&quot;Couldn't create thread&quot;);
              
              spawn_food(&amp;s-&gt;snake_list[i], s-&gt;map,s-&gt;food,s-&gt;info);
              update_tail(&amp;s-&gt;snake_list[i]);
              set_gameover(&amp;s-&gt;snake_list[i], s-&gt;map);
              usleep(s-&gt;snake_list[i].sleep_time);
          }
      }
      free(s-&gt;food);
      free(s-&gt;pid);
      free(s-&gt;snake_list);
      
      pthread_exit(0);
  }
  </code></pre>
  <pre><code>void initialize(snake_thread* s,int argc,char** argv)
  {
      s-&gt;snake_list = calloc(s-&gt;info-&gt;size,sizeof(snake) );
      s-&gt;pid = calloc(s-&gt;info-&gt;size, sizeof(pthread_t) );
      s-&gt;food=calloc(s-&gt;info-&gt;size,sizeof(snake_food));
      //does some stuff and passes s to other functions   
  }
  </code></pre>
  <pre><code>void Read_args(int argc, char** argv,snake_thread* s)
  {
      int c;
      if (argc &gt; 1)
          while ((c = getopt(argc, argv, &quot;x:y:f:&quot;)) != -1)
              switch (c)
              {
              case 'x':
                  s-&gt;info-&gt;width_provided = true;
                  s-&gt;map-&gt;width = atoi(optarg);
                  break;
              case 'y':
                  s-&gt;info-&gt;height_provided = true;
                  s-&gt;map-&gt;height = atoi(optarg);
                  break;
              case 'f':
                  s-&gt;info-&gt;file_name_provided = true;
                  strcpy(s-&gt;info-&gt;file,optarg);
                  break;
              default:
                  usage(argv[0]);
                  break;
              }
      else usage(argv[0]);
      if(!(s-&gt;info-&gt;file))
      {
          strcpy(s-&gt;info-&gt;file,getenv(&quot;$SNAKEFILE&quot;));
          if(!(s-&gt;info-&gt;file))
          {
              printf(&quot;Warning, No save file provided\n&quot;);
          }
      }
      init_size(argc,s-&gt;info);
     
      //if(argc&gt;optind) ERR(&quot;optind err&quot;);
      s-&gt;map-&gt;map_elem_pos = calloc(s-&gt;map-&gt;height,sizeof(char*));
      if (s-&gt;map-&gt;map_elem_pos == NULL) ERR(&quot;Malloc error for elements of map&quot;);
  
      for (int i = 0; i &lt; s-&gt;map-&gt;height; i++)
          s-&gt;map-&gt;map_elem_pos[i] = calloc(s-&gt;map-&gt;width,sizeof(char));
  }
  </code></pre>
  <pre><code>int main(int argc, char** argv)
  {
      pthread_t pid;
      snake_thread s[1]
      Read_args(argc, argv, s);
      if (access(s-&gt;info-&gt;file, F_OK) != 0)
          initialize(s,argc,argv);
      int err = pthread_create(&amp;s-&gt;pid2, NULL, run_snake_threads, (void*)s);
      if (err) ERR(&quot;Couldn't create thread&quot;);
      pthread_join(s-&gt;pid2, NULL);
  }
  </code></pre>