user1563074 user1563074 - 1 month ago 5
C Question

How can a simple assignment cause a segmentation fault?

I'm making a program to split a file into lexemes but I'm unfamiliar with C and I'm getting a weird segmentation error. The following code runs and prints:

1
2
Segmentation Fault: 11


I've looked up other causes to segmentation faults and I'm not doing anything to an array after 2. What am I doing wrong? How can a simple assignment cause a segmentation fault?

#include <stdio.h>
#define CHAR_CODE 1
#define NUM_CODE 2
#define RESERVED_CHAR_CODE 3
#define SPACE_CODE 4
#define ERR_CODE 5
char token[16];
char line[128];
int lineLen = 0;
int counter = 0;
FILE *file;
void cleanToken(){
for(int i = 0 ; i < 16; i++){
token[i] = 0;
}
}
void cleanLine(){
for(int i = 0 ; i < 128; i++){
line[i] = 0;
}
}
void next(){
cleanToken();
printf("1\n");
char c;
if(counter == lineLen){
printf("2\n");
lineLen = 0;
printf("3");
cleanLine();
printf("4");
counter = 0;
while((c=getc(file)) != 10 && c != EOF){
if(c!=32){
line[lineLen] = c;
lineLen++;
}
printf("%d\n", lineLen);
}
printf("%s\n", line);
}
c = line[counter];
int type = getType(c);
while(getType(c)==type){
token[counter] = c;
counter = counter + 1;
c = line[counter];
if(c == EOF | c == 4 | type == RESERVED_CHAR_CODE){
break;
}
}
}
int getType(int c){
if((c > 96 & c < 123) | (c>64 & c < 91)){
return CHAR_CODE;
} else if(c < 58 & c > 46){
return NUM_CODE;
} else if(c == 32){
return SPACE_CODE;
} else if(c == 33 | c == 34 | (c > 36 & c < 44) | c == 45 | c == 47 | (c > 58 & c < 63)){

return RESERVED_CHAR_CODE;
} else {
return ERR_CODE;
}
}

int main(){
int c;
FILE* file;
file = fopen("test.txt", "r");
for(int i = 0; i < 10 ;i++){
next();
printf("%s\n", token);
}
return 0;
}

Answer

There are a number of problems in your code, most of which will be shown by using -Wall when you compile, but specifically, the crash is being caused by attempting to access the global variable file, which has not been initialized.

You shadowed it in main() with another variable with the same name. You initialized that one, but not the global one being accessed by next().

Also, your printf statements are insufficient for debugging, as there is no guarantee that the output buffer will be flushed to your console before the program crashes. If you add \n to the printf("3") and printf("4") lines, you will see that they get printed before the crash. Alternatively, you could call fflush(stdout) after the printf() calls to ensure that they are printed. By doing this, you will see that the crash is not happening as a result of the assignment as it appears.

A debugger such as gdb would be very helpful in debugging your code.

Comments