Структура и сегментация ошибки - PullRequest
2 голосов
/ 21 октября 2019

У меня буквально проблемы с отладкой действительной причины segfault . Программа предназначена для сбора информации о студентах. Управляемое меню используется для выбора списка возможных опций, таких как 1 для добавления учащегося, 2 для отображения содержимого скрытого файла и 3 для отображения информации.

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

Пожалуйста, введите следующий выбор

1: Добавить информацию
2: Обновить информацию
3: Показать информацию
0:Выход

Введите число: 2 Ошибка сегментации (ядро сброшено)

Редактировать: я настоятельно рекомендовал отлаживать с помощью gdb. Вот результат:

/ gdb-test

Please enter the following choice

    1: Add Information
    2: Update Information
    3: Display Information
    0: Exit

Введите число: 3

Program received signal SIGSEGV, Segmentation fault.
0x0000555555554ff5 in display (resident=0x0, file1=0x0, res=0x0)
    at maincode.c:130
130     *resident = fopen(file1, "r");
(gdb) 

Ниже приведеноисходный код.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_SIZE 100

struct student {
    char registration[MAX_SIZE], location[MAX_SIZE], faculty[MAX_SIZE];
        int yearOfBirth, monthOfBirth, dayOfBirth, layerArch1, layerArch2, levelOfStudy, graduatingYear;    
};

int writeInfo(FILE **resident, FILE **transient, const char *file1, const char *file2, struct student *res, struct student *tra);
int readTransient(FILE **transient, const char *file2, struct student *tra);
int display(FILE **resident, const char *file1, struct student *res);

/********************************************************************************/

int main (int argc, char **argv) {

    FILE *resident, *transient;

    struct student *res = (struct student *) malloc(sizeof(struct student));
    struct student *tra = (struct student *) malloc(sizeof(struct student));

    char file1[MAX_SIZE] = "resident.txt";
    char file2[MAX_SIZE] = "transient.txt";

    int choice = -1;

    while (choice !=0) {
        printf("\n\tPlease enter the following choice\n\n");
        printf("*****************************************************\n");
        printf("\t\t1: Add Information\n");
        printf("\t\t2: Read Information\n");
        printf("\t\t3: Display Information\n");
        printf("\t\t0: Exit\n");
        printf("*****************************************************\n");

        printf("\nEnter a number: ");
        scanf("%d", &choice);

        switch (choice) {
            case 0:
                exit(1);
            case 1:
                writeInfo(&resident, &transient, file1, file2, res, tra);
                break;
            case 2: 
                readTransient(&transient, file2, tra);
                break;
            case 3: 
                display(&resident, file1, res);
                break;
            default:
                printf("Please enter either 1, 2 or 3! O for Exit\n\n");
                break;
        }
    }

    return 0;
}

int writeInfo(FILE **resident, FILE **transient, const char *file1, const char *file2, struct student *res, struct student *tra) {

        *resident = fopen(file1, "w");
        *transient = fopen(file2, "w"); 

        if (*resident == NULL) {
            fprintf(stderr, "\nError open file\n");
            exit(1);
        }

        if (*transient == NULL) {
            fprintf(stderr, "\nError open file\n");
            exit(1);
        }

        printf("Enter a registration number [7 digits]: ");
            scanf("%s", res->registration);

            printf("Enter location (location in currency, AUS CND SIN): ");
            scanf("%s", res->location);
            strcpy(tra->location, res->location);

            printf("Enter faculty (ENG BUS SCI MED): ");
            scanf("%s", res->faculty);
        strcpy(tra->faculty, res->faculty);

            printf("Enter birth of year (19XX 200X): ");
            scanf("%d", &res->yearOfBirth);

            printf("Enter birth of month (XX): ");
            scanf("%d", &res->monthOfBirth);
        tra->monthOfBirth = res->monthOfBirth;

            printf("Enter birth of date (XX): ");
            scanf("%d", &res->dayOfBirth);
        tra->dayOfBirth = res->dayOfBirth;

            printf("Enter level of study (1 -first, 2- second, 3- third, 4-fourth, 5 - other): ");
            scanf("%d", &res->levelOfStudy);
        tra->levelOfStudy = res->levelOfStudy;

            printf("Enter graduating year (XXXX): ");
            scanf("%d",&res->graduatingYear);
        tra->graduatingYear = res->graduatingYear;

            printf("Enter layer of Architecture 1 (0-sensing, 1-network, 2-smart(hidden), 3-devices): ");
            scanf("%d",&res->layerArch1);

            printf("Enter layer of Architecture 2 (0-sensing, 1-network, 2-smart(hidden), 3-devices): ");
            scanf("%d", &res->layerArch2);
        tra->layerArch2 = res->layerArch2;

        //write entire sturcture to Student file
        fwrite(&res, sizeof(struct student), 1, *resident);

        fwrite(&tra, sizeof(struct student), 1, *transient);

        fclose(*resident);
        fclose(*transient);
}

int display(FILE **resident, const char *file1, struct student *res) {
    memset(&res, 0, sizeof(struct student));
    *resident = fopen(file1, "r");

    if (*resident == NULL) {
        fprintf(stderr, "\nError opening file!\n\n");
        exit(1);
    }

    while(fread(&res, sizeof(struct student), 1, *resident)) {
        printf("%d%s%d%d%d%d%d%s%d%s%d%d\n\n", res->yearOfBirth, res->registration, res->monthOfBirth, res->dayOfBirth, res->layerArch1, res->layerArch2, res->levelOfStudy, res->location, res->graduatingYear, res->faculty, res->dayOfBirth, res->monthOfBirth);
    }

    fclose(*resident);
}

int readTransient(FILE **transient, const char *file2, struct student *tra) {
    memset(&tra, 0, sizeof(struct student));
    *transient = fopen(file2, "r");

    if (*transient == NULL) {
        fprintf(stderr, "\nError opening file!\n\n");
        exit(1);
    }

    while(fread(&tra, sizeof(struct student), 1, *transient)) {
        printf("%d%d%s%d%s%d%d\n\n", tra->layerArch2, tra->levelOfStudy, tra->location, tra->graduatingYear, tra->faculty, tra->dayOfBirth, tra->monthOfBirth);
    }

    fclose(*transient);
}

В чем собственно проблема? Может ли кто-нибудь помочь уточнить / изменить?

Спасибо. Я высоко ценю вашу помощь и сотрудничество.

1 Ответ

0 голосов
/ 21 октября 2019

Заменить

while(fread(&tra, sizeof(struct student), 1, *transient))

на

while(fread(tra, sizeof(struct student), 1, *transient))

Обоснование: функция fread нуждается в указателе, т.е. адрес блока памяти , но вы передаете адрес переменной, содержащей указатель .

Измените остальные функции соответствующим образом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...