IT工单系统新增工单覆盖旧数据问题求助(附C语言代码)
问题根源
旧工单数据被覆盖的核心原因是**createTicket函数中使用栈上的局部字符数组存储用户输入,然后直接把数组地址赋值给Ticket结构体的指针成员**。栈内存在函数执行完毕后会被回收复用,每次调用createTicket时,这些局部数组的内存位置重复,新输入会覆盖旧内容,导致所有Ticket结构体的字符串指针都指向同一块栈内存,最终显示的都是最后一次输入的数据。
修复方案
为每个字符串成员动态分配堆内存(用malloc+strcpy),确保每个工单的字符串数据存储在独立内存中,不会被覆盖。同时补充内存释放逻辑,避免内存泄漏。
修改后的核心函数
1. 修复createTicket函数
#include <string.h> // 需新增头文件,用于strlen和strcpy Ticket* createTicket() { Ticket* newTicket = (Ticket*)malloc(sizeof(Ticket)); if (newTicket == NULL) { printf("Memory allocation failed\n"); exit(1); } char email[120]; char name[120]; char date[480]; char issue[480]; int num = 0; // 姓名:读取后动态分配内存并复制内容 printf("What's the name: "); scanf("%s", name); // 数组名本身是地址,无需& newTicket->name = malloc(strlen(name) + 1); // +1存储字符串终止符 if (newTicket->name == NULL) { printf("Memory allocation failed for name\n"); exit(1); } strcpy(newTicket->name, name); // 邮箱 printf("What's the email: "); scanf("%s", email); newTicket->email = malloc(strlen(email) + 1); if (newTicket->email == NULL) { printf("Memory allocation failed for email\n"); exit(1); } strcpy(newTicket->email, email); // 日期 printf("What's the date: "); scanf("%s", date); newTicket->date = malloc(strlen(date) + 1); if (newTicket->date == NULL) { printf("Memory allocation failed for date\n"); exit(1); } strcpy(newTicket->date, date); // 优先级(原逻辑保留) while (num > 5 || num < 1) { printf("What's the priority of the issue (1-5): "); scanf("%d", &num); if (num > 5 || num < 1) { printf("Invalid input. Enter a number between 1 and 5\n"); } else { newTicket->priority = num; } } // 问题描述 printf("What's the issue? (maximum characters: 120): "); scanf("%s", issue); newTicket->issue_description = malloc(strlen(issue) + 1); if (newTicket->issue_description == NULL) { printf("Memory allocation failed for issue description\n"); exit(1); } strcpy(newTicket->issue_description, issue); newTicket->is_closed = 0; newTicket->issue_solution = "None"; // 字符串字面量无需动态分配 newTicket->next = NULL; return newTicket; }
2. 补充内存释放逻辑
原代码仅释放Ticket结构体本身,需新增字符串成员的释放:
// 在main函数的内存释放部分修改 Ticket* temp; while (head != NULL) { temp = head; head = head->next; // 先释放字符串成员 free(temp->name); free(temp->email); free(temp->date); free(temp->issue_description); // issue_solution是字符串字面量,无需free free(temp); // 最后释放结构体本身 }
完整修复代码
#include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct ticket { char *name; char *email; char *date; int priority; char *issue_description; int is_closed; char *issue_solution; struct ticket* next; }Ticket; Ticket* createTicket() { Ticket* newTicket = (Ticket*)malloc(sizeof(Ticket)); if (newTicket == NULL) { printf("Memory allocation failed\n"); exit(1); } char email[120]; char name[120]; char date[480]; char issue[480]; int num = 0; printf("What's the name: "); scanf("%s", name); newTicket->name = malloc(strlen(name) + 1); if (newTicket->name == NULL) { printf("Memory allocation failed for name\n"); exit(1); } strcpy(newTicket->name, name); printf("What's the email: "); scanf("%s", email); newTicket->email = malloc(strlen(email) + 1); if (newTicket->email == NULL) { printf("Memory allocation failed for email\n"); exit(1); } strcpy(newTicket->email, email); printf("What's the date: "); scanf("%s", date); newTicket->date = malloc(strlen(date) + 1); if (newTicket->date == NULL) { printf("Memory allocation failed for date\n"); exit(1); } strcpy(newTicket->date, date); while (num > 5 || num < 1) { printf("What's the priority of the issue (1-5): "); scanf("%d", &num); if (num > 5 || num < 1) { printf("Invalid input. Enter a number between 1 and 5\n"); } else { newTicket->priority = num; } } printf("What's the issue? (maximum characters: 120): "); scanf("%s", issue); newTicket->issue_description = malloc(strlen(issue) + 1); if (newTicket->issue_description == NULL) { printf("Memory allocation failed for issue description\n"); exit(1); } strcpy(newTicket->issue_description, issue); newTicket->is_closed = 0; newTicket->issue_solution = "None"; newTicket->next = NULL; return newTicket; } void addTicketAtEnd(Ticket** head, Ticket* newTicket) { if (*head == NULL) { *head = newTicket; return; } Ticket* temp = *head; while (temp->next != NULL) { temp = temp->next; } temp->next = newTicket; } void printList(Ticket* head) { if (head == NULL) { printf("The list is empty.\n"); return; } printf("Ticket List:\n"); Ticket* temp = head; while (temp != NULL) { printf("Name: %s\n", temp->name); printf("Email: %s\n", temp->email); printf("Date: %s\n", temp->date); printf("Priority: %d\n", temp->priority); printf("Issue: %s\n", temp->issue_description); printf("Solution: %s\n", temp->issue_solution); printf("-------------------------\n"); temp = temp->next; } } Ticket* insertTicket(Ticket* head) { Ticket* newTicket = createTicket(); Ticket* temp = head; if(head == NULL){ return newTicket; } if (head->priority <= newTicket->priority){ newTicket->next = head; return newTicket; } else { while(1){ if (temp->next == NULL){ addTicketAtEnd(&head, newTicket); return head; }else if(temp->next->priority <= newTicket->priority){ newTicket->next = temp->next; temp->next = newTicket; return head; } else { temp = temp->next; } } } } int main() { Ticket* head = NULL; int option = 1; while (1){ if (option == 1){ head = insertTicket(head); } else if (option == 2) { // 后续可实现关闭工单逻辑 } else if (option == 3){ printList(head); } else if (option == 4){ break; } while (1){ printf("Enter a value between 1-4. 1. Add a ticket. 2. resolve a ticket. 3. print all tickets. 4. Exit: "); scanf("%d", &option); if(option > 4 || option < 1){ printf("Invalid input. Enter a number between 1 and 4\n"); } else { break; } } } Ticket* temp; while (head != NULL) { temp = head; head = head->next; free(temp->name); free(temp->email); free(temp->date); free(temp->issue_description); free(temp); } return 0; }
内容的提问来源于stack exchange,提问作者Griffin Zee
相关产品推荐
相关产品推荐

