C быстрой сортировкой структуры вызывает ошибку сегментации - PullRequest
2 голосов
/ 21 февраля 2012

Программа читает строку за строкой из файла и сохраняет информацию в структуре. Все работает, кроме сортировки массива структур. Например, в конце, когда я печатаю структуру (код, включенный в конец), она работает совершенно нормально.

Проблема (ошибка сегментации) возникает, когда я вызываю qsort.

Кроме того, печать студентов [0] .lastName работает нормально, но печать студентов [1] .lastName возвращает (ноль), что тоже сбивает с толку.

Я посмотрел везде, и мой код кажется очень похожим на то, что было опубликовано как правильные решения для структур сортировки, поэтому я очень запутался.

Определение структуры в заголовке main:

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

Выделение структуры в основном методе (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);
}

Проблема: вызов быстрой сортировки (причина для 8 в том, что есть 8 записей, которые работают и загружены, даже меньше 8 не работает).:

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

Компаратор для быстрой сортировки:

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

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

Причина, по которой я знаю, что данные загружаются нормально, в том, что печать работает совершенно нормально:

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);
        }
}

Что он печатает (я включил только 2 из 8, которые были напечатаны, без печати NULL):

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

Спасибо!

Ответы [ 3 ]

5 голосов
/ 21 февраля 2012

Строка:

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

выделяет память для самой структуры, но не для строк, на которые ссылаются указатели:

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

Каждая из них занимает достаточно памяти дляуказатель.Вам нужно будет выделить память для строк отдельно:

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

Запись в память, которой вы не владеете, - это всегда хороший способ получить неожиданный урок отладки ошибок рикошета: вы, вероятно,в конечном итоге получить ошибку или повреждение памяти, но это может быть в области кода, которая, по-видимому, совершенно не связана с фактическим источником проблемы.

1 голос
/ 21 февраля 2012

При условии STUDENT_DATA> = 8, есть только одно возможное объяснение: одно или несколько ваших полей lastName никогда не инициализировались и содержат NULL или мусор.Если ваш цикл, инициализирующий эти поля, содержал ту же ошибку, что и ваш цикл, печатавший его (используя students=students+sizeof(StudentInformation) вместо students++), вот почему.

0 голосов
/ 21 февраля 2012

Вы сказали Calling quicksort (the reason for the 8 is because there are 8 entries.

Это неверно.Вы должны передать количество элементов в массиве (STUDENT_DATA в вашем случае).

...