Использование realloc для массива структур - PullRequest
0 голосов
/ 13 июля 2011

Я часами чесал голову по этому поводу.Это считывает данные из текстового файла в структуру (каждая строка имеет четыре строки, и каждая строка представляет нового студента).Я получаю ошибку сегмента на realloc (ближе к концу).У меня есть подозрение, что я не понимаю, как указатель взаимодействует с malloc / realloc.

struct student* createInitialStudentArray(FILE *fp) {
    char buf[20+1] = {0};
    int word = 1, studcount = 1;
    struct student* studentArray = malloc(sizeof(struct student));
    assert(studentArray != NULL);
    while (fscanf(fp, " %20s", buf) != EOF) {
        if (word % 4 == 1) {
            sscanf(buf, "%4d", &studentArray[studcount].studentID);
            word++;
        }
        else if (word % 4 == 2) {
            strcpy(studentArray[studcount].lastName, buf);
            word++;
        }
        else if (word % 4 == 3) {
            strcpy(studentArray[studcount].firstName, buf);
            word++;
        }
        else if (word % 4 == 0) {
            sscanf(buf, "%10lld", &studentArray[studcount].phoneNumber);
            word = 1;
            studcount++;
            studentArray = realloc(studentArray, studcount * sizeof(struct student));
            assert(studentArray != NULL);
        }
    }

    return studentArray;
}

Что вызывает эту ошибку сегмента?

Заранее спасибо,

Гусь

Ответы [ 2 ]

3 голосов
/ 13 июля 2011

Если ваш массив содержит studcount элементов, то studentArray[studcount] находится за концом массива, и запись в него запрещена. Допустимые элементы для доступа: от 0 до studcount-1. Вы должны заменить studentArray[studcount] на studentArray[studcount-1] везде, чтобы записать в последний элемент.

Обратите внимание, что выполнение этого способа даст вам значение studcount, которое слишком велико на 1, когда цикл завершен, потому что последний элемент массива всегда пуст или не завершен.

Как упомянуто в комментариях pmg, другое решение состоит в том, чтобы инициализировать studcount равным 0, что устранит обе вышеупомянутые проблемы, но затем вам необходимо убедиться, что выделено место как минимум для элементов studcount+1, прежде чем писать новую один.

0 голосов
/ 13 июля 2011

Ваша структура loop и scanf выглядит неправильно ..

Сначала вы читаете строку (scanf в условии while), затем int (word == 1), затем другую строку (снова условие, word == 2), другую строку ( в то время как условие снова, word == 3), и, наконец, еще одна строка и long long int (word == 4).

Я бы переписал твой внутренний цикл с помощью переключателя

/* pseudo-code */
while (fgets(buf, sizeof buf, stdin)) {
    /* realloc here */
    chk = sscanf(buf, "%4d%20s%20s%10lld",
                &studentArray[studcount].studentID,
                studentArray[studcount].lastName,
                studentArray[studcount].firstName,
                &studentArray[studcount].phoneNumber);
    if (chk != 4) /* deal with error */;
}
...