YohanRoth
YohanRoth

Reputation: 3253

Segmentation fault in C. What is the reason?

I am getting segmentation fault in C and I have no idea what is the reason. As far as I know segmentation fault occurs when system run our of memory. I checked my loops and they seem to have clear termination conditions. Thus, I am confused what causes my code to crash. As I checked this fault should occurs in mygetline or readlines functions. Is there any debugger that I can use to find our why program crashes?

#include <stdio.h>
#include <string.h>
#define MAXLINE 100
#define MAXLINENUM 10

int readlines(char *lines[]);
int mygetline(char line[]); /* getline: read a line into s, returns length */
void writelines(char *lines[], int nlines);

int main()
{

int i = 0;

char *lines[MAXLINE];
i = readlines(lines);
writelines(lines, i);

return 0;
}

int mygetline(char line[]){
    int i, c;

    for(i = 0; i < MAXLINE-1 && (c = getchar()) != '\n' && c != EOF; i++){
        line[i] = c;
    }
    line[i] = '\0';
    return i;
}

int readlines(char *lines[]){

    int i, c;
    i = 0;

    while((c = mygetline(lines++)) > 0 && i < MAXLINENUM){ //line[i]
        i++;
    }

    lines[--i] = '\0';
    return i;
}

void writelines(char *lineptr[], int nlines) {
    int i;
    for (i = 0; i < nlines; i++) 
        printf("%s\n", lineptr[i]);
}

Upvotes: 1

Views: 143

Answers (4)

Sathish
Sathish

Reputation: 3870

The reason for the segmentation fault is the memory allocation. You can not allocate memory like char *lines[MAXLINE];.

Try the following code If you are Using 1D array

char *lines;
lines=(char *)malloc(MAXLINE*sizeof(char));

If you are using 2D array go with this code

char **lines;
lines=(char **)malloc(MAXLINENUM*sizeof(char *));
for(i=0;i<MAXLINENUM;i++)
lines[i]=(char *)malloc(MAXLINE*sizeof(char));

Upvotes: 1

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726569

The reason that you get a segfault is that your code reads the data into lines without allocating any memory for the characters that you read.

Your main allocates memory for the pointers to strings, but it does not initialize these pointers. You need to add code to set these pointers to valid blocks of memory, for example, by allocating some max number of characters with malloc:

while(i < MAXLINENUM) {
    lines[i] = malloc(MAXLINE);
    if (!mygetline(lines[i++])) {
        break;
    }
}

Also note that you confused MAXLINE with MAXLINENUM in the declaration of lines.

Upvotes: 1

Sean
Sean

Reputation: 62472

You created an array char *lines[MAXLINE] which is an array of pointers. However, you've not initialized those pointers, so they're pointing to garbage. You then pass the garbage pointer into mygetline which writes to the garbage pointer, and this is the problem.

Not only do you need to allocate memory for the line to be stores in, but you also need to get mygetline how many characters it can read. If you allocate space for 10 characters, but the user enters 20 you're going to have a similar problem.

Upvotes: 2

David Heffernan
David Heffernan

Reputation: 612954

The reason for the segmentation fault is that you don't allocate any storage for the strings. You declare an array of char* here:

char *lines[MAXLINE];

But nowhere do you ever allocate memory to hold the actual strings.

To continue using an array of char*, allocated that way, you'd need to use malloc to allocate memory for the actual strings.

lines[i] = malloc(...);

Obviously you'll need to:

  • Decide how much memory to allocate for each string.
  • Call free to dispose of the memory when you are done with it.
  • Add some code to check that you don't write beyond the end of any of your buffers.

Upvotes: 4

Related Questions