The CLI compiler compiles and works fine on windows. Compilation works fine on Linux, but a segmentation error occurs during operation.
I turned to stackoverflow for help and found some questions similar to what I was going to ask what the valgrind I just installed (woo!) Suggested.
So, I ran my program through valgrind and received a depressingly large amount of output, but I will start with the first error message:
==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.
The problem seems to be in readnumberfromfile , and I looked through it and I canβt find what is wrong with it!
Can anyone shed some light?
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<11 && ch!=separator && 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)<=maxvalue ? atoi(buff) : maxvalue;//convert string to number and make sure it in range free(buff); return number; }
This is called from getrecordsfromfile , if used:
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->question=readtextfromfile(MAXTEXTLENGTH,separator); newvocab->answer=readtextfromfile(MAXTEXTLENGTH,separator); newvocab->info=readtextfromfile(MAXTEXTLENGTH,separator); newvocab->hint=readtextfromfile(MAXTEXTLENGTH,separator); newvocab->right=readnumberfromfile(1,separator); newvocab->counter=readnumberfromfile(0,separator); newvocab->known=readnumberfromfile(3,separator); switch (newvocab->known) { case 0: newvocablist = &n2l;break; case 1: newvocablist = &norm;break; case 2: newvocablist = &known;break; case 3: newvocablist = &old;break; } addtolist(newvocab,newvocablist); if (newvocab->question==NULL||newvocab->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; }
The full source can be created from https://github.com/megamasha/Vocab-Tester
A few notes: I'm trying to help myself, I did my research, looked at similar questions and myself learned about valgrind.
I am still a relative novice, and although I appreciate the solutions (WHAT to do to fix this), knowledge (HOW to fix or avoid it next time) is even more useful. I am here (and very passionate) to learn.