C语言程序运行报错Process returned -1073741819 (0xC0000005)求助
我写了一段C语言代码完成练习,编译没有警告和错误,但运行时直接崩溃,报错Process returned -1073741819 (0xC0000005)。我自己找了很久没找到原因,作为编程新手,求各位给点建议。
users.csv文件格式要求:<身份证号>;<观影数量>;<年龄>;<职业>,示例数据如下:
1234;18;10;student 3253;22;3;sommelier 1;16;100;teacher 1743;50;5;retired 9654;28;18;student
我的代码
/* Write a program that takes in input a file with data relative to users from a streaming site, loads them in memory in a structured type variable and, after having sorted them by age in ascending order, writes in a new file the data relative to only the users that are students. */ #include <stdio.h> #include <stdlib.h> #include <string.h> const int MAX = 100; // I wasn't able to use a preprocessor command (such as '#define MAX 100') | error: expected identifier or '(' before numeric constant | so I declared a constant global variable typedef struct { int id, age, watched_movies; char occupation[30]; } USER[100]; // can't initialize with MAX ( ==> cannot initialize arrays with variable sized elements) //Written 'MAX' as 'max' to avoid variable shadowing and confusion in function building void sort_users(USER* U, int max); void print_students(USER* U, int max); int main(void) { FILE* usersPtr; if ((usersPtr = fopen("users.csv", "r")) == NULL) { puts("File 'users.csv' could not be opened."); exit(1); } else { USER U[100] = {{{0, 0, 0, ""}}}; // added braces to remove compiler warning for (int i = 0; i < MAX; ++i) { U[i]->id = 99999; U[i]->age = 0; U[i]->watched_movies = 0; strcpy(U[i]->occupation, ""); } int i = 0; char string[60] = {""}; char* strPtr; while (!feof(usersPtr)) { fscanf(usersPtr, "%s", string); strPtr = strtok(string, ";"); U[i]->id = atoi(strPtr); strPtr = strtok(NULL, ";"); U[i]->age = atoi(strPtr); strPtr = strtok(NULL, ";"); U[i]->watched_movies = atoi(strPtr); strPtr = strtok(NULL, ";"); strcpy(U[i]->occupation, strPtr); i++; } strPtr = NULL; sort_users(U, MAX); print_students(U, MAX); printf("%s", "The 'students.csv' file has been created and filled with the relevant pieces of information.\n"); fclose(usersPtr); usersPtr = NULL; } return 0; } void sort_users(USER* U, int max) // ("bubble sorting") { for (int i = 0; i < max; ++i) { for (int j = max - 1; j != i; --j) { if (U[j]->age <= U[i]->age) { USER T[1] = {{{0, 0, 0, ""}}}; // create a temporary array of structs (of 1 element) T[0]->id = U[i]->id; T[0]->age = U[i]->age; T[0]->watched_movies = U[i]->watched_movies; strcpy(T[0]->occupation, U[i]->occupation); T[i]->id = U[j]->id; T[i]->age = U[j]->age; T[i]->watched_movies = U[j]->watched_movies; strcpy(T[i]->occupation, U[j]->occupation); T[j]->id = U[0]->id; T[j]->age = U[0]->age; T[j]->watched_movies = U[0]->watched_movies; strcpy(T[j]->occupation, U[0]->occupation); } } } } void print_students(USER* U, int max) { FILE* studentsPtr; if ((studentsPtr = fopen("students.csv", "w")) == NULL) { puts("File 'students.csv' could not be created."); exit(1); } else { for (int i = 0; i < max; ++i) { if (strcmp(U[i]->occupation, "student") == 0) { fprintf(studentsPtr, "%d,%d,%d,%s\n", U[i]->id, U[i]->age, U[i]->watched_movies, U[i]->occupation); } } fclose(studentsPtr); studentsPtr = NULL; } }
问题排查与修复建议
结构体定义完全错误:你把
USER定义成了包含100个结构体的数组类型,导致后续所有U[i]->的写法都是在错误地操作指针,直接触发内存越界。正确的做法是先定义单个用户结构体,再声明数组:typedef struct { int id, age, watched_movies; char occupation[30]; } User; #define MAX 100 User U[MAX];访问成员时用
.而不是->,比如U[i].id。MAX宏定义问题:之前用
#define MAX 100报错,肯定是你加了分号或者语法错误。宏定义不需要分号,正确写法就是#define MAX 100,用宏定义比全局const更适合指定数组大小。feof循环逻辑错误:
while (!feof(usersPtr))会导致最后一次循环重复读取(因为feof是读取失败后才置位),还可能让i超过MAX导致数组越界。改成读取成功才进入循环:int i = 0; char string[60]; while (i < MAX && fscanf(usersPtr, "%s", string) == 1) { // 解析逻辑 i++; }排序函数逻辑混乱且越界:sort_users里的临时数组T只有1个元素,但你却访问
T[i]、T[j],直接越界写内存,这是崩溃的直接原因之一。冒泡排序的正确逻辑是交换相邻元素,用单个临时结构体即可:void sort_users(User* U, int count) { for (int i = 0; i < count - 1; ++i) { for (int j = 0; j < count - i - 1; ++j) { if (U[j].age > U[j+1].age) { User temp = U[j]; U[j] = U[j+1]; U[j+1] = temp; } } } }注意这里传入的应该是实际读取的用户数量
i,而不是MAX,避免处理未初始化的空数据。初始化冗余:原来的
USER U[100] = {{{0, 0, 0, ""}}};写法复杂,改成User U[MAX] = {0};就能完成所有成员的初始化,不需要额外循环赋值。
修复后的完整代码
#include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX 100 typedef struct { int id, age, watched_movies; char occupation[30]; } User; void sort_users(User* U, int count); void print_students(User* U, int count); int main(void) { FILE* usersPtr = fopen("users.csv", "r"); if (!usersPtr) { puts("File 'users.csv' could not be opened."); exit(1); } User U[MAX] = {0}; int i = 0; char string[60]; char* strPtr; while (i < MAX && fscanf(usersPtr, "%s", string) == 1) { strPtr = strtok(string, ";"); if (strPtr) U[i].id = atoi(strPtr); strPtr = strtok(NULL, ";"); if (strPtr) U[i].age = atoi(strPtr); strPtr = strtok(NULL, ";"); if (strPtr) U[i].watched_movies = atoi(strPtr); strPtr = strtok(NULL, ";"); if (strPtr) strncpy(U[i].occupation, strPtr, sizeof(U[i].occupation)-1); // 用strncpy避免缓冲区溢出 i++; } sort_users(U, i); print_students(U, i); puts("The 'students.csv' file has been created and filled with the relevant pieces of information."); fclose(usersPtr); return 0; } void sort_users(User* U, int count) { for (int i = 0; i < count - 1; ++i) { for (int j = 0; j < count - i - 1; ++j) { if (U[j].age > U[j+1].age) { User temp = U[j]; U[j] = U[j+1]; U[j+1] = temp; } } } } void print_students(User* U, int count) { FILE* studentsPtr = fopen("students.csv", "w"); if (!studentsPtr) { puts("File 'students.csv' could not be created."); exit(1); } for (int i = 0; i < count; ++i) { if (strcmp(U[i].occupation, "student") == 0) { fprintf(studentsPtr, "%d;%d;%d;%s\n", U[i].id, U[i].watched_movies, U[i].age, U[i].occupation); // 输出格式和输入一致用分号,或者按需求改逗号 } } fclose(studentsPtr); }
内容的提问来源于stack exchange,提问作者Gisvaldo

