C语言数据库项目运行报错zsh: illegal hardware instruction ./main求助
C语言数据库项目运行报错:
zsh: illegal hardware instruction ./main 问题背景
编译项目后运行出现zsh: illegal hardware instruction ./main错误,该错误在引入malloc后出现。预期流程为:通过roomAvailability检测目标文件不存在,调用roomDataIn创建文件并写入数据,再用roomDataOut读取文件内容。
项目代码文件
databaseLogic.c
/* databaseLogic.c */ #include <stdlib.h> #include <stdio.h> const int MAX_STR_LEN = 20; int roomAvailability(int roomChecked) { FILE* fileAvailable; char filename[46]; sprintf(filename, "../../databaseManagement/roomParent/room%d.txt", roomChecked); fileAvailable = fopen(filename, "r"); if(fileAvailable == NULL) { return 1; } else { return 0; } fclose(fileAvailable); } int roomDataIn(char userData[10][MAX_STR_LEN], int roomRequested) { FILE *openRoom; char dataInBuffer[MAX_STR_LEN]; char filename[46]; sprintf(filename, "../../databaseManagement/roomParent/room%d.txt", roomRequested); openRoom = fopen(filename, "r"); fclose(openRoom); if(openRoom == NULL) { openRoom = fopen(filename, "w"); for(int i=0;i<9;i++) { sprintf(dataInBuffer, "%s\n", userData[i]); fputs(dataInBuffer, openRoom); } } else { printf("not found"); return -1; } fclose(openRoom); return 0; } char *roomDataOut(int roomRequested, int requestedLine) { FILE *openRoom; char filename[46]; char *pulledData = (char *)malloc(MAX_STR_LEN*8); sprintf(filename, "../../databaseManagement/roomParent/room%d.txt", roomRequested); openRoom = fopen(filename, "r"); if(openRoom != NULL) { char tempStorage[MAX_STR_LEN]; for(int i=0;i<requestedLine-1;i++) { fgets(tempStorage, 20, openRoom); } fgets(pulledData, 20, openRoom); fclose(openRoom); return pulledData; } printf("failure"); return "failure"; }
databaseLogic.h
/* databaseLogic.h */ extern int roomDataIn(char *userData, int requestedRoom); extern int roomAvailability(int requestedRoom); extern char *roomDataOut(int requestedRoom, int requestedLine);
main.c
/* main.c */ #include <stdio.h> #include "checkIn.h" #include "checkOut.h" #include "databaseLogic.h" const char num1[2]; int main() { char test[10][10] = {"1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890"}; printf("%d", roomAvailability(3)); printf("%d", roomDataIn(*test, 3)); printf("%s", roomDataOut(3, 3)); return 0; }
编译命令
clang main.c checkIn.c checkOut.c databaseLogic.c -o main ./main
错误原因分析
- 函数声明与定义不匹配:
databaseLogic.h中roomDataIn声明为char *userData,但实际定义是二维数组char userData[10][MAX_STR_LEN],调用时传入*test(一维指针),类型不兼容引发未定义行为。 fclose执行逻辑错误:roomDataIn中先调用fclose(openRoom)再判断openRoom == NULL,若fopen失败,openRoom为NULL,调用fclose(NULL)会触发未定义行为,这是硬件指令错误的直接诱因。roomAvailability资源泄漏:fclose(fileAvailable)在return语句之后,永远不会执行,导致文件句柄泄漏。- 返回值类型冲突:
roomDataOut成功时返回动态分配内存的指针,失败时返回字符串字面量,调用者无法区分,若尝试free字面量指针会引发错误。 - 未初始化全局变量:
main.c中const char num1[2]未初始化,属于不良编码习惯。
修复方案
1. 修正函数声明与调用匹配
修改databaseLogic.h中roomDataIn的声明:
extern int roomDataIn(char userData[10][20], int requestedRoom);
main中调用时直接传入二维数组名:
printf("%d", roomDataIn(test, 3));
2. 修复roomAvailability的fclose位置
将fclose移至return之前:
int roomAvailability(int roomChecked) { FILE* fileAvailable; char filename[46]; sprintf(filename, "../../databaseManagement/roomParent/room%d.txt", roomChecked); fileAvailable = fopen(filename, "r"); if(fileAvailable == NULL) { return 1; } else { fclose(fileAvailable); return 0; } }
3. 修正roomDataIn的文件操作逻辑
先判断文件是否打开成功,再执行关闭或创建操作:
int roomDataIn(char userData[10][MAX_STR_LEN], int roomRequested) { FILE *openRoom; char dataInBuffer[MAX_STR_LEN]; char filename[46]; sprintf(filename, "../../databaseManagement/roomParent/room%d.txt", roomRequested); openRoom = fopen(filename, "r"); if(openRoom == NULL) { openRoom = fopen(filename, "w"); if(openRoom == NULL) { perror("Failed to create file"); return -2; } for(int i=0;i<9;i++) { sprintf(dataInBuffer, "%s\n", userData[i]); fputs(dataInBuffer, openRoom); } fclose(openRoom); } else { printf("Room file already exists\n"); fclose(openRoom); return -1; } return 0; }
4. 统一roomDataOut的返回值处理
始终返回动态分配内存,失败时写入错误字符串:
char *roomDataOut(int roomRequested, int requestedLine) { FILE *openRoom; char filename[46]; char *pulledData = (char *)malloc(MAX_STR_LEN); if(pulledData == NULL) { perror("malloc failed"); return NULL; } sprintf(filename, "../../databaseManagement/roomParent/room%d.txt", roomRequested); openRoom = fopen(filename, "r"); if(openRoom != NULL) { char tempStorage[MAX_STR_LEN]; for(int i=0;i<requestedLine-1;i++) { if(fgets(tempStorage, MAX_STR_LEN, openRoom) == NULL) { strcpy(pulledData, "failure"); fclose(openRoom); return pulledData; } } if(fgets(pulledData, MAX_STR_LEN, openRoom) == NULL) { strcpy(pulledData, "failure"); } fclose(openRoom); return pulledData; } strcpy(pulledData, "failure"); return pulledData; }
main中使用后释放内存:
int main() { char test[10][10] = {"1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890", "1234567890"}; printf("%d\n", roomAvailability(3)); printf("%d\n", roomDataIn(test, 3)); char *data = roomDataOut(3, 3); printf("%s\n", data); free(data); return 0; }
5. 清理未使用的全局变量
删除main.c中未使用的const char num1[2];。
验证修复
重新编译运行:
clang main.c checkIn.c checkOut.c databaseLogic.c -o main ./main
此时会依次输出1(房间文件不存在)、0(文件创建写入成功)、第三行内容1234567890。
内容的提问来源于stack exchange,提问作者Sealpup
相关产品推荐
相关产品推荐

