MarkMan
MarkMan

Reputation: 150

Can someone explain why I'm getting segmentation fault 11?

Here is my code:

int main() {

    typedef struct {

        int recordCount;
        char *firstName;
        char *secondName;
        char *id;
        char *email;

    }student;

    student *students = malloc(sizeof(*students));

    int i = 0;

    while (students[i].firstName[0] != '.'){

        students[i].firstName = (char *)malloc(sizeof(char*));
        scanf("%s", students[i].firstName);
        i++;
        students = realloc(students, sizeof(students) * (i + 1));

    }
}

When I run it through a for loop it works, I'm pretty sure it's just something silly going on with my while loop.

Upvotes: 3

Views: 119

Answers (4)

Syed Waris
Syed Waris

Reputation: 1074

There are plenty of issues in your code.

  1. When you are using malloc, you actually specify the data type and not the pointer type which is I believe is not your intent here. If you are specifying a pointer type with sizeof, the pointer will point to a memory location having the size of the pointer. This is not what you want in this case.
  2. After the line student *students = malloc ... . The students will point to a memory location which will hold zero values in firstName. You need to use malloc for these. Since you are not doing this you are getting a segmentation fault because you are dereferencing an invalid pointer (pointing to location 0). You are trying to access it first and using malloc afterwards.

Upvotes: 0

dbush
dbush

Reputation: 223882

malloc returns a block of uninitialized memory. So students[i].firstName is an uninitialized pointer which you attempt to dereference. Reading and dereferencing an uninitialized pointer invokes undefined behavior, which in this case manifests as a crash.

When you do allocate space for the firstName member, you only allocate sizeof(char*) bytes for it which is the size of a pointer, not necessarily the length of a string you would want to read.

Create a buffer to read strings into that's big enough for what you might need, then use strdup to create a copy to assign to the relevant pointer.

student *students = NULL;
int i = 0;
char str[100];

scanf("%99s", str);
while (str[0] != '.'){
    students = realloc(students, sizeof(*students) * (i+1));
    students[i].firstName = strdup(str);
    i++;

    scanf("%99s", str);
}

Upvotes: 5

adrtam
adrtam

Reputation: 7211

If you

student *students = malloc(sizeof(*students));

you are allocating size of one pointer. What you want to do is instead

student *students = malloc(sizeof(students));

and for the same reason, students[i].firstName = (char *)malloc(sizeof(char*)) quite surely do not have enough memory for your name as well, try malloc(sizeof(char)*100) or so.

Upvotes: -2

paxdiablo
paxdiablo

Reputation: 881423

For a start,

students[i].firstName = (char *)malloc(sizeof(char*));

allocates enough space for a character pointer, typically four or eight bytes.

While there are some names that will fit in that (such as Pax or Bob), the vast majority probably won't.

You need to allocate enough space for the largest name (and string terminator), such as with:

#define MAX_NAME_LEN 100
students[i].firstName = malloc(MAX_NAME_LEN + 1);

Upvotes: 3

Related Questions