【发布时间】: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