【问题标题】:Struct and segmentation fault结构和分段错误
【发布时间】:2020-02-17 14:41:04
【问题描述】:

我确实在调试 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);
}

真正的问题是什么?有人可以帮助澄清/修改吗?

谢谢。非常感谢您的帮助与合作。

【问题讨论】:

  • 我推荐阅读How to debug small programs。特别是关于使用调试器的部分;例如,gdb 应该告诉您导致段错误的确切行。
  • edit你的问题告诉我们你做了什么样的调试。我希望您已经在 Valgrind 或类似的检查器中运行了您的minimal reproducible example,并使用诸如 GDB 之类的调试器进行了调查。确保您也启用了全套编译器警告。这些工具告诉了你什么,它们缺少什么信息?并阅读 Eric Lippert 的 How to debug small programs
  • @0x5453我已经完成了编辑和调试。但我还是有点失落
  • @TobySpeight 我已经编辑了我的问题线程并显示了 gdb 调试(哪一行/部分)

标签: c pointers struct segmentation-fault


【解决方案1】:

替换

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

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

理由: fread 函数需要一个指针,即 内存块的地址,但您传递的是 包含指针的变量的地址 .

相应地修改其余函数。

【讨论】:

  • 感谢您的回答。我已经这样做了,阅读时,输出错误
  • 但是它解决了段错误吗?我的回答只是解决了段错误问题。
  • 它没有输出想要的输出。但是,它确实解决了分割问题。
猜你喜欢
  • 2014-01-18
  • 1970-01-01
  • 2021-06-12
  • 1970-01-01
  • 1970-01-01
  • 2011-08-24
  • 2023-04-04
  • 2016-06-11
  • 1970-01-01
相关资源
最近更新 更多