title: Valgrind - 2,064 bytes in 1 blocks are possibly lost in loss record 57 of 64
body: <p>Yesterday I asked a question so that you could help me debug a program which consists basically in reading a variable-size line from the standard input. After a while I thought I had solved all problems, but today, valgrind is still complaining.</p>
  
  <p>I compiled my program with:</p>
  
  <pre><code>gcc -g -o find_all_words find_all_words.c
  </code></pre>
  
  <p>and then I used valgrind as follows:</p>
  
  <pre><code>valgrind --leak-check=full --show-leak-kinds=all ./find_all_words hello world
  </code></pre>
  
  <p>it points also to another part in the <code>while</code> loop of my code:</p>
  
  <pre><code>==15333== Memcheck, a memory error detector
  ==15333== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
  ==15333== Using Valgrind-3.12.0.SVN and LibVEX; rerun with -h for copyright info
  ==15333== Command: ./find_all_words hello world
  ==15333== 
  Enter your favourite citation: hello world, how are you today?
  line = hello world, how are you today?
  Input arguments:
  1 = hello
  2 = world
  ==15333== 
  ==15333== HEAP SUMMARY:
  ==15333==     in use at exit: 30,666 bytes in 189 blocks
  ==15333==   total heap usage: 276 allocs, 87 frees, 36,976 bytes allocated
  ==15333== 
  ==15333== 2,064 bytes in 1 blocks are possibly lost in loss record 57 of 64
  ==15333==    at 0x100009104: malloc_zone_malloc (in /usr/local/Cellar/valgrind/HEAD/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
  ==15333==    by 0x1004F4EFD: _objc_copyClassNamesForImage (in /usr/lib/libobjc.A.dylib)
  ==15333==    by 0x1004E8182: protocols() (in /usr/lib/libobjc.A.dylib)
  ==15333==    by 0x1004E8093: readClass(objc_class*, bool, bool) (in /usr/lib/libobjc.A.dylib)
  ==15333==    by 0x1004E5C13: gc_init (in /usr/lib/libobjc.A.dylib)
  ==15333==    by 0x1004ED24E: objc_initializeClassPair_internal(objc_class*, char const*, objc_class*, objc_class*) (in /usr/lib/libobjc.A.dylib)
  ==15333==    by 0x1004FA132: layout_string_create (in /usr/lib/libobjc.A.dylib)
  ==15333==    by 0x1004E883C: realizeClass(objc_class*) (in /usr/lib/libobjc.A.dylib)
  ==15333==    by 0x1004E8300: copySwiftV1MangledName(char const*, bool) (in /usr/lib/libobjc.A.dylib)
  ==15333==    by 0x1004E82E9: copySwiftV1MangledName(char const*, bool) (in /usr/lib/libobjc.A.dylib)
  ==15333==    by 0x1004E82E9: copySwiftV1MangledName(char const*, bool) (in /usr/lib/libobjc.A.dylib)
  ==15333==    by 0x1004E82E9: copySwiftV1MangledName(char const*, bool) (in /usr/lib/libobjc.A.dylib)
  ==15333== 
  ==15333== 4,096 bytes in 1 blocks are still reachable in loss record 63 of 64
  ==15333==    at 0x100008E3B: malloc (in /usr/local/Cellar/valgrind/HEAD/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
  ==15333==    by 0x1001E2AF5: __smakebuf (in /usr/lib/system/libsystem_c.dylib)
  ==15333==    by 0x1001E66D0: __srefill0 (in /usr/lib/system/libsystem_c.dylib)
  ==15333==    by 0x1001E67B8: __srefill (in /usr/lib/system/libsystem_c.dylib)
  ==15333==    by 0x1001DFA66: fgets (in /usr/lib/system/libsystem_c.dylib)
  ==15333==    by 0x100000A73: readline (find_all_words.c:26)
  ==15333==    by 0x100000E0D: main (find_all_words.c:94)
  ==15333== 
  ==15333== LEAK SUMMARY:
  ==15333==    definitely lost: 0 bytes in 0 blocks
  ==15333==    indirectly lost: 0 bytes in 0 blocks
  ==15333==      possibly lost: 2,064 bytes in 1 blocks
  ==15333==    still reachable: 4,096 bytes in 1 blocks
  ==15333==         suppressed: 24,506 bytes in 187 blocks
  ==15333== 
  ==15333== For counts of detected and suppressed errors, rerun with: -v
  ==15333== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 17 from 17)
  </code></pre>
  
  <p>And this is my program:</p>
  
  <pre><code>#include&lt;stdio.h&gt;
  #include&lt;stdlib.h&gt;
  #include&lt;string.h&gt;
  
  /**
  * Gets and a variable-size line from the standard input.
  */
  char * readline(){
  
      size_t n = 10;
      char* final = calloc(n, sizeof(char));
      final[0] = '\0';
      char* tmp; // used for allocating memory temporarily
  
      // constant buffer size used to store the read characters
      // before storing them in the final buffer
      char buf[10];
  
      while(fgets(buf, sizeof buf, stdin) != NULL) {
  
          if(buf[strlen(buf) - 1] == '\n') {
  
              if(strlen(buf) &gt; 1) {
  
                  if((n - strlen(final)) &lt; (strlen(buf) + 1)) {
                      // -1 because buf contains also \n at the end
                      n = strlen(final) + strlen(buf);
                      tmp = calloc(n, sizeof(char));
  
                      for(int i=0; i &lt;= strlen(final); ++i)
                          tmp[i] = final[i];
  
                      free(final);
  
                  } else {
                      tmp = final;
                  }
  
                  int i, j;
                  for(i = strlen(tmp), j = 0; j &lt;= (strlen(buf) - 2); ++i, ++j)
                      tmp[i] = buf[j];
  
                  tmp[i] = '\0';
                  final = tmp;
                  tmp = NULL;
              }
  
              break;
  
          } else { // no newline inserted at the end
  
              if((n - strlen(final)) &lt; (strlen(buf) + 1)) {
                  n *= 2;
                  tmp = calloc(n, sizeof(char));
  
                  for(int i = 0; i &lt;= strlen(final); ++i)
                      tmp[i] = final[i];
  
                  free(final);
  
              } else {
                  tmp = final;
              }       
  
              // Starts inserting from the '\0' char
              // Insert also the '\0' at the end
              for(int i = strlen(tmp), j = 0; j &lt;= 9; ++i, ++j)
                  tmp[i] = buf[j];
  
              final = tmp;
              tmp = NULL;
          }
      }
  
      return final;
  }
  
  
  int main(int argc, char *argv[]){
      if(argc &lt; 2){
          fprintf(stderr, "usage: at least one string as command-line argument.\n");
          exit(1);
      } else {
  
          printf("Enter your favourite citation: ");
  
          char *line = readline();
  
          printf("line = %s\n", line);
  
          printf("Input arguments:\n");
  
          for(int i=1; i &lt; argc; ++i)
              printf("%i = %s\n", i, argv[i]);
  
          free(line);
      }
  
  
  
      return 0;
  }
  </code></pre>
  
  <p>Thanks for any help!</p>