简体   繁体   中英

C quick sort of a struct causes segmentation fault

The program is reading line by line from a file and storing info in a struct. Everything works except for sorting the array of structs. For example, at the end when I'm printing the struct(code included at the end), it works completely fine.

The problem (segmentation fault) occurs when I call the qsort.

Also, printing students[0].lastName works fine, but printing students[1].lastName returns a (null), that too is confusing.

I've looked everywhere and my code seems very similar to what has been posted as correct solutions to sorting structs, so I'm very confused.

Defining struct in header of main:

// DEFINE STRUCT
typedef struct _StudentInformation  {
    int term;
    int studentId;
    char *lastName;
    char *firstName;
    char *subject;
    int catalogNumber;
    char *section;
} StudentInformation;

Allocating the struct in main method (STUDENT_DATA=50):

// ALLOCATE AN ARRAY OF STUDENTS (STRUCT)
    StudentInformation *students;
    if ((students = malloc(STUDENT_DATA*sizeof(StudentInformation)))==NULL) {
        scanf("Error can't allocate enough students!\n");
        exit(1);
}

The problem: Calling quicksort (the reason for the 8 is because there are 8 entries THAT WORK and are LOADED, even less than 8 doesn't work).:

qsort(students, 8, sizeof(StudentInformation), comparator);

Comparator for quicksort:

int comparator (const void * a, const void * b) {
    StudentInformation *s1 = (StudentInformation*)a;
    StudentInformation *s2 = (StudentInformation*)b;

    return strcmp(s1->lastName, s2->lastName);
}

The reason I know data is loaded fine is because printing works completely fine:

void printInformation (StudentInformation *students) {
    // PRINT EVERYTHING
        while(students->firstName!=NULL) {
            printf("%-s, %s %15d %4d %4s%d %7s\n",
                    students->lastName,students->firstName,students->term,
                    students->studentId, students->subject,students->catalogNumber,
                    students->section);

            // Increment
            students=students+sizeof(StudentInformation);
        }
}

What it prints (i only included 2 out of the 8 that were printed, no NULLS printed):

Castille, Michael Jr            1201 103993269  CSE230     R03
Boatswain, Michael R.            1201 105515018  CSE230     R01

Thank you!

The line:

if ((students = malloc(STUDENT_DATA*sizeof(StudentInformation)))==NULL)

allocates memory for the structure itself, but not for the strings that are referenced by pointers:

char *lastName;
char *firstName;
char *subject;
char *section;

Each of those occupies enough memory for a pointer. You'll need to allocate memory for the strings separately:

if ((lastName = malloc((LAST_NAME_LEN + 1) * sizeof(char))) == NULL) {
  // Error
}
if ((firstName = ...

Writing to memory that you don't own is always a good way to get an unexpected lesson in debugging ricochet-errors: you'll probably get a segfault or memory corruption eventually, but it may be in an area of code that appears to be totally unrelated to the actual source of the problem.

Provided STUDENT_DATA >= 8, there's only one possible explanation, which is that one or more of your lastName fields was never initialized and contains NULL or garbage. If your loop initializing these fields contained the same error as your loop printing it out (using students=students+sizeof(StudentInformation) instead of students++ ), that would be why.

You said Calling quicksort (the reason for the 8 is because there are 8 entries .

This is incorrect. you should pass the number of elements in the array ( STUDENT_DATA in your case).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM