I’ve just bought “The C programming language” by K&R, and doing my best to do the exercises therein (if you know the book, it’s exercise 1.20).
The program is meant to take input from the keyboard, and convert tab characters to appropriate amount of spaces, specified by TABLENGTH.
The code is below. When I try to run it I get segmentation fault.
detab.c:
#include <stdio.h>
#define TABLENGTH 8
#define MAXLINE 1000
int getline(char line[], int len);
int main()
{
char line[MAXLINE];
int length;
while((length = getline(line, MAXLINE)) > 0) {
printf("%s");
}
}
int getline(char line[], int len)
{
int i = 0;
int c;
for(i = 0; i < (MAXLINE - 1) &&
((c = getchar()) != EOF && c != '\n'); i++) {
// if c is tab, replace with spaces
if(c == '\t') {
while((TABLENGTH - (i % TABLENGTH)) != 0) {
line[i] = ' ';
i++;
}
i--;
continue;
}
}
line[i] = c;
}
if(c == '\n') {
line[i] = c;
i++;
}
line[i] = '\0';
return i;
}
The call to
printfis a likely cause of a segfault. It will try to interpret some arbitrary data on the stack as a pointer to a 0-terminated
chararray.A certain way to a segfault is the loop in case of a
'\t':Since
i >= 0andTABLENGTH > 0, you always have0 <= (i % TABLENGTH) < TABLENGTH, so whenever you encounter a tab, you enter an infinite loop adding spaces tolinebeyond the allocated space and that will sooner or later cause a segfault when it tries to write spaces outside the process memory or into a read-only part of the memory. An easy, although not very elegant fix is changing the loop toa different fix could be using a separate counter or a
switchwith a fall-through.