title: Invalid read using valgrind
body: <p>After a compilation with no warnings and errors for my file <em>reorg.c</em>, I am running the program using <code>Valgrind</code> and I am getting the following output. I am trying to understand why I am getting a segmentation fault but I can't really find something wrong with line 35:</p>
  <pre><code>Memcheck, a memory error detector
    ==29338== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
    ==29338== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info
    ==29338== Command: ./reorg /opt/lsde/dataset-sf100/
    ==29338==
    ==29338== Invalid read of size 2
    ==29338==    at 0x109398: main (reorg.c:35)
    ==29338==  Address 0x12cb4008 is not stack'd, malloc'd or (recently) free'd
    ==29338==
    ==29338==
    ==29338== Process terminating with default action of signal 11 (SIGSEGV)
    ==29338==  Access not within mapped region at address 0x12CB4008
    ==29338==    at 0x109398: main (reorg.c:35)
    ==29338==  If you believe this happened as a result of a stack
    ==29338==  overflow in your program's main thread (unlikely but
    ==29338==  possible), you can try to increase the size of the
    ==29338==  main thread stack using the --main-stacksize= flag.
    ==29338==  The main thread stack size used in this run was 8388608.
    ==29338==
    ==29338== HEAP SUMMARY:
    ==29338==     in use at exit: 15,280 bytes in 10 blocks
    ==29338==   total heap usage: 10 allocs, 0 frees, 15,280 bytes allocated
    ==29338==
    ==29338== LEAK SUMMARY:
    ==29338==    definitely lost: 5,120 bytes in 5 blocks
    ==29338==    indirectly lost: 0 bytes in 0 blocks
    ==29338==      possibly lost: 0 bytes in 0 blocks
    ==29338==    still reachable: 10,160 bytes in 5 blocks
    ==29338==         suppressed: 0 bytes in 0 blocks
    ==29338== Rerun with --leak-check=full to see details of leaked memory
    ==29338==
    ==29338== For lists of detected and suppressed errors, rerun with: -s
    ==29338== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
    Segmentation fault (core dumped)
  </code></pre>
  <p>This is the code of the reorg.c program.</p>
  <pre><code>  #include &lt;stdio.h&gt;
    #include &lt;stdlib.h&gt;
    #include &lt;string.h&gt;
    #include &lt;sys/mman.h&gt;
    #include &lt;sys/types.h&gt;
    #include &lt;sys/stat.h&gt;
    #include &lt;fcntl.h&gt;
    #include &lt;unistd.h&gt;
  
  
    #include &quot;utils.h&quot;
  
    Person *person_map;
    unsigned int *knows_map;
    unsigned short *interest_map;
    unsigned long person_num = 0;
  
    int main(int argc, char *argv[]) {
      unsigned long file_length;
       
      interest_map = (unsigned short *) mmapr(makepath(argv[1], &quot;interest&quot;, &quot;bin&quot;), &amp;file_length);
      printf(&quot;amin1&quot;);
      knows_map    = (unsigned int *)   mmapr(makepath(argv[1], &quot;knows&quot;,    &quot;bin&quot;), &amp;file_length);
      printf(&quot;amin2&quot;);
      person_map   = (Person *)         mmapr(makepath(argv[1], &quot;person&quot;,   &quot;bin&quot;), &amp;file_length);
      printf(&quot;amin3&quot;);
      knows_map    = (unsigned int *)   mmapr(makepath(argv[1], &quot;knows&quot;,    &quot;bin&quot;), &amp;file_length);
      printf(&quot;knows&quot;);
      person_map   = (Person *)         mmapr(makepath(argv[1], &quot;person&quot;,   &quot;bin&quot;), &amp;file_length);
      printf(&quot;person&quot;);   
      person_num   = file_length/sizeof(person_map);
      int counter=0;
      FILE* fp_knows2 = fopen(makepath(argv[1], &quot;knows2&quot;, &quot;bin&quot;), (char*) &quot;w&quot;);
      FILE* fp_person2 = fopen(makepath(argv[1], &quot;person2&quot;, &quot;bin&quot;), (char*) &quot;w&quot;);
      long knows2_bytesize;
      int *knows2_map;
      int *person2_map;
      long person2_bytesize;
          for(long i=0; i&lt;person_num; i++) {
              for(long j = 0; j &lt; person_map[i].knows_n; j++) {
  
                  int friend = knows_map[person_map[i].knows_first+j]; // person in my knows-list
                  if (person_map[friend].location == person_map[i].location) {
                      counter++;
                      fwrite(&amp;friend, 1,sizeof(int), fp_knows2);
                  }
              }
              if(counter &gt; 0){
                  fwrite(&amp;person_map[i], 1, sizeof(int), fp_person2);
              }
              counter=0;
          }
          fclose(fp_knows2);
          fclose(fp_person2);
          person2_map = (int*) mmapr(makepath(argv[1], &quot;person2&quot;,&quot;bin&quot;), &amp;person2_bytesize);
          knows2_map = (int*) mmapr(makepath(argv[1], &quot;knows2&quot;,&quot;bin&quot;), &amp;knows2_bytesize);
  
      return 0;
    }
  </code></pre>
  <p>And this is the code of the <em>utils.h</em> program that am including in:</p>
  <pre><code>   #define REPORTING_N 1000000
     #define LINEBUFLEN 1024
  
      typedef unsigned long byteoffset;
      typedef unsigned int  entrycount;
  
  
      typedef struct {
      unsigned long  person_id;
      unsigned short birthday;
      unsigned short location;
      unsigned long  knows_first;
      unsigned short knows_n;
      unsigned long  interests_first;
      unsigned short interest_n;
    } Person;
  
    void parse_csv(char* fname, void (*line_handler)(unsigned char nfields, char** fieldvals)) {
      long nlines = 0;
  
      FILE* stream = fopen(fname, &quot;r&quot;);
      if (stream == NULL) {
          fprintf(stderr, &quot;Can't read file at %s\n&quot;, fname);
          exit(-1);
      }
      char line[LINEBUFLEN];
      char* tokens[10];
      unsigned int col, idx;
      tokens[0] = line;
  
        while (fgets(line, LINEBUFLEN, stream)) {
          col = 0;
          // parse the csv line into array of strings
          for (idx=0; idx&lt;LINEBUFLEN; idx++) { 
              if (line[idx] == '|' || line[idx] == '\n') {
                  line[idx] = '\0';
                  col++;
                  tokens[col] = &amp;line[idx+1];
              } // lookahead to find end of line
              if (line[idx+1] == '\0') {
                  break;
              }
          }
          (*line_handler)(col, tokens);
          nlines++;
          if (nlines % REPORTING_N == 0) {
              printf(&quot;%s: read %lu lines\n&quot;, fname, nlines);
          }
      }
      fclose(stream);
      }
  
  
      FILE* open_binout(char* filename) {
      FILE* outfile;
      outfile = fopen(filename, &quot;wb&quot;);
      if (outfile == NULL) {
          fprintf(stderr, &quot;Could not open %s for writing\n&quot;, filename);
          exit(-1);
        }
         return outfile;
        }
  
    
      unsigned short birthday_to_short(char* date) {
      unsigned short bdaysht;
      char dmbuf[3];
      dmbuf[2] = '\0';
      dmbuf[0] = *(date + 5);
      dmbuf[1] = *(date + 6);
      bdaysht = atoi(dmbuf) * 100;
      dmbuf[0] = *(date + 8);
      dmbuf[1] = *(date + 9);
      bdaysht += atoi(dmbuf);
      return bdaysht;
      }
  
      void* mmapr(char* filename, byteoffset *filelen) {
      int fd;
      struct stat sbuf;
      void *mapaddr;
  
      if ((fd = open(filename, O_RDONLY)) == -1) {
          fprintf(stderr, &quot;failed to open %s\n&quot;, filename);
          exit(1);
      }
  
      if (stat(filename, &amp;sbuf) == -1) {
          fprintf(stderr, &quot;failed to stat %s\n&quot;, filename);
          exit(1);
      }
      
      mapaddr = mmap(0, sbuf.st_size, PROT_READ, MAP_SHARED, fd, 0);
      if (mapaddr == MAP_FAILED) {
          fprintf(stderr, &quot;failed to mmap %s\n&quot;, filename);
          exit(1);
      }
      *filelen = sbuf.st_size;
      return mapaddr;
      }
  
      char* makepath(char* dir, const char* file, const char* ext) {
      char* out = (char*) malloc(1024), *sep = (char*) &quot;&quot;;
          if (strlen(dir) &amp;&amp; dir[strlen(dir)-1] != '/') sep = (char*) &quot;/&quot;;
      sprintf(out, &quot;%s%s%s.%s&quot;, dir, sep, file, ext);
      return out;
      }
  </code></pre>