title: Trying to debug a c program segmentation fault using output from valgrind
body: <p>A CLI program of mine compiles and runs fine on windows. Compiles fine on linux, but causes a segmentation fault when running.</p>
  
  <p>I turned to stackoverflow for help, and found a few questions similar to what I was going to ask that suggested valgrind, which I just happen to have installed (woo!).</p>
  
  <p>So I ran my program through valgrind, and got a depressingly large amount of output, but I shall start with the first error message:</p>
  
  <pre><code>==11951== Command: ./vt
  ==11951== 
  Loading...
  Load default database? (y/n)y
  Opened input file vtdb.~sv, reading contents...
  ==11951== Invalid write of size 1
  ==11951==    at 0x400FA9: readnumberfromfile (in /home/rob/Documents/programming/c/vocabtest/vt)
  ==11951==    by 0x400C21: getrecordsfromfile (in /home/rob/Documents/programming/c/vocabtest/vt)
  ==11951==    by 0x401FFD: main (in /home/rob/Documents/programming/c/vocabtest/vt)
  ==11951==  Address 0x53b05bb is 0 bytes after a block of size 11 alloc'd
  ==11951==    at 0x4C28FAC: malloc (vg_replace_malloc.c:236)
  ==11951==    by 0x400EAC: readnumberfromfile (in /home/rob/Documents/programming/c/vocabtest/vt)
  ==11951==    by 0x400C21: getrecordsfromfile (in /home/rob/Documents/programming/c/vocabtest/vt)
  ==11951==    by 0x401FFD: main (in /home/rob/Documents/programming/c/vocabtest/vt)
  ==11951== 
  ...finished.
  1180 entries read from vtdb.~sv.
  </code></pre>
  
  <p>The problem seems to be in <code>readnumberfromfile</code>, and I've looked through it, and I can't seem to find what's wrong with it!</p>
  
  <p>Can anyone shed some light?</p>
  
  <pre><code>int readnumberfromfile (int maxvalue,char separator)
  {
      int number, i=0;
      char ch;
      char * buff = (char *)malloc(11);//allocate enough space for an 10-digit number and a terminating null
      if (!buff) {printf("Memory allocation failed!\n");return 0;}//return 0 and print error if alloc failed
      if (!maxvalue) maxvalue=MAXINTVALUE;
  
      ch=getc(inputfile);
      while (!isdigit(ch))
      {
          if (ch == separator||ch=='\n'||ch==EOF) {fprintf(stderr,"Format error in file\n");return 0;}//if no number found(reached separator before digit), print error and return 0
          ch = getc(inputfile);//cycle forward until you reach a digit
      }
      while (i&lt;11 &amp;&amp; ch!=separator &amp;&amp; ch!='\n')//stop when you reach '~', end of line, or when number too long
      {
          buff[i++]=ch;
          ch = getc(inputfile); //copy number from file to buff, one char at a time
      }
      buff[i] = '\0';//terminate string
      number = atoi(buff)&lt;=maxvalue ? atoi(buff) : maxvalue;//convert string to number and make sure it's in range
      free(buff);
      return number;
  }
  </code></pre>
  
  <p>This is called from <code>getrecordsfromfile</code> if that's of any use:</p>
  
  <pre><code>void getrecordsfromfile(char * inputfilename,char separator)
  {
      int counter = 0;
      struct vocab * newvocab;
      struct listinfo * newvocablist;
      if (!(inputfile = fopen(inputfilename, "r")))
      {
          printf("Unable to read input file. File does not exist or is in use.\n");
      }    
      else
      {
          printf("Opened input file %s, reading contents...\n",inputfilename);
          while (!feof(inputfile))
          {
              newvocab = (struct vocab *)malloc(sizeof(struct vocab));
              if (!newvocab)
              {
                  printf("Memory allocation failed!\n");
                  return;
              }
              else
              {
                  newvocab-&gt;question=readtextfromfile(MAXTEXTLENGTH,separator);
                  newvocab-&gt;answer=readtextfromfile(MAXTEXTLENGTH,separator);
                  newvocab-&gt;info=readtextfromfile(MAXTEXTLENGTH,separator);
                  newvocab-&gt;hint=readtextfromfile(MAXTEXTLENGTH,separator);
                  newvocab-&gt;right=readnumberfromfile(1,separator);
                  newvocab-&gt;counter=readnumberfromfile(0,separator);
                  newvocab-&gt;known=readnumberfromfile(3,separator);
  
                  switch (newvocab-&gt;known)
                  {
                      case 0: newvocablist = &amp;n2l;break;
                      case 1: newvocablist = &amp;norm;break;
                      case 2: newvocablist = &amp;known;break;
                      case 3: newvocablist = &amp;old;break;
                  }
  
                  addtolist(newvocab,newvocablist);
                  if (newvocab-&gt;question==NULL||newvocab-&gt;answer==NULL)
                  {
                      printf("Removing empty vocab record created from faulty input file...\n");
                      removefromlist(newvocab,newvocablist,1);
                  }
                  else counter++;
              }
          }
          fclose(inputfile);
          printf("...finished.\n%i entries read from %s.\n\n",counter,inputfilename);
      }
      return;
  }
  </code></pre>
  
  <p>Full source can be gitted from <a href="https://github.com/megamasha/Vocab-Tester" rel="nofollow">https://github.com/megamasha/Vocab-Tester</a></p>
  
  <p>A couple of notes: I am trying to help myself, I have done my research, looked at similar questions and found out about valgrind myself.</p>
  
  <p>I am still a relative beginner though, and while I appreciate solutions (WHAT to do to fix it), yet more useful is knowledge (HOW to fix or avoid it myself next time). I am here (and very keen) to learn.</p>