使用DMA与结构体数组存储员工信息时姓名出现垃圾值的求助
问题排查:动态内存分配结构体数组的姓名垃圾值问题
编程初学者,基于动态内存分配(DMA)和结构体数组编写员工信息采集代码,功能为采集员工姓名、地址、员工ID及年龄,并按姓名升序排列。当前遇到的问题:当员工数量设置为2及以上时,输出的姓名显示为垃圾值,无法正常展示输入内容。
原代码
#include <stdio.h> #include <stdlib.h> #include <string.h> struct emp_details { char *address; char *name; char *Emp_ID; int age; }; void ascen_str(struct emp_details* employees_data,int num_of_emp); int main() { int num_of_emp; printf("Enter the number of employees: "); scanf("%d",&num_of_emp); struct emp_details* employees_data = malloc(num_of_emp*sizeof (employees_data)); int i=0; for(int i=0;i<num_of_emp;i++) { employees_data[i].name=(char*)malloc(30*sizeof(char)); printf("Employe %d enter the Name: ",i+1); scanf("%s",employees_data[i].name); printf("%s",employees_data[i].name); getchar(); //sscanf(emp_name,"%s\n",employees_data[i].name); //fgets(employees_data[i].name,30,stdin); employees_data[i].address = (char*)malloc(100*sizeof(char)); printf("Employe %d enter the Address: ",i+1); //scanf("%s",employees_data[i].address); fgets(employees_data[i].address,30,stdin); employees_data[i].Emp_ID=(char*)malloc(10*sizeof(char)); printf("Employe %d enter the Employe ID: ",i+1); scanf("%s",employees_data[i].Emp_ID); printf("Employe %d enter the Age: ",i+1); scanf("%d",&employees_data[i].age); } printf("\n\tEmploye details before sorting\n"); for(int i=0;i<num_of_emp;i++) { printf("Employe %d Name: %s\n",i+1,employees_data[i].name); printf("Employe %d Address: %s",i+1,employees_data[i].address); printf("Employe %d Age: %d\n",i+1,employees_data[i].age); printf("Employe %d ID: %s\n\n",i+1,employees_data[i].Emp_ID); } ascen_str(employees_data,num_of_emp); free(employees_data); } void ascen_str(struct emp_details* employees_data, int num_of_emp) { struct emp_details temp; for (int i = 0; i < num_of_emp; i++) { for (int j = i + 1; j < num_of_emp; j++) { if (strcmp(employees_data[i].name, employees_data[j].name) > 0) { temp = employees_data[i]; employees_data[i] = employees_data[j]; employees_data[j] = temp; } } } printf("\n\tEmploye details in ascending order by name\n"); for (int i = 0; i < num_of_emp; i++) { printf("Employe Name: %s\n",employees_data[i].name); printf("Employe Address: %s",employees_data[i].address); printf("Employe Age: %d\n",employees_data[i].age); printf("Employe ID: %s\n\n",employees_data[i].Emp_ID); } }
问题根源及修复方案
1. 结构体数组内存分配错误(核心问题)
原代码分配结构体数组时使用sizeof(employees_data),但employees_data是指针类型,其大小在32位系统为4字节、64位为8字节,远小于struct emp_details的实际大小。这会导致分配的内存空间不足,后续写入数据时越界,破坏内存中的姓名指针,最终显示垃圾值。
修复:将分配语句改为:
struct emp_details* employees_data = malloc(num_of_emp * sizeof(struct emp_details));
2. 输入处理逻辑混乱
scanf("%d", &num_of_emp)后会在输入缓冲区留下换行符,后续getchar()仅消耗一次,处理多个员工时仍会有残留;fgets读取长度与分配的内存空间不匹配,且会保留换行符导致输出异常;- 输入姓名后多余的
printf("%s", employees_data[i].name)属于调试代码,可移除。
修复:统一输入处理逻辑,用getchar()清空缓冲区残留换行符,调整fgets读取长度并去除换行符:
// 输入员工数量后清空缓冲区 scanf("%d", &num_of_emp); getchar(); // 循环内输入处理 for(int i=0;i<num_of_emp;i++) { employees_data[i].name = malloc(30 * sizeof(char)); printf("Employee %d enter the Name: ", i+1); fgets(employees_data[i].name, 30, stdin); employees_data[i].name[strcspn(employees_data[i].name, "\n")] = '\0'; employees_data[i].address = malloc(100 * sizeof(char)); printf("Employee %d enter the Address: ", i+1); fgets(employees_data[i].address, 100, stdin); employees_data[i].address[strcspn(employees_data[i].address, "\n")] = '\0'; employees_data[i].Emp_ID = malloc(10 * sizeof(char)); printf("Employee %d enter the Employee ID: ", i+1); fgets(employees_data[i].Emp_ID, 10, stdin); employees_data[i].Emp_ID[strcspn(employees_data[i].Emp_ID, "\n")] = '\0'; printf("Employee %d enter the Age: ", i+1); scanf("%d", &employees_data[i].age); getchar(); }
3. 内存泄漏问题
原代码仅释放了结构体数组的内存,未释放每个结构体成员(name、address、Emp_ID)分配的内存,会造成内存泄漏。
修复:在程序结束前遍历数组,逐一释放成员内存:
for(int i=0; i<num_of_emp; i++) { free(employees_data[i].name); free(employees_data[i].address); free(employees_data[i].Emp_ID); } free(employees_data);
修复后的完整代码
#include <stdio.h> #include <stdlib.h> #include <string.h> struct emp_details { char *address; char *name; char *Emp_ID; int age; }; void ascen_str(struct emp_details* employees_data, int num_of_emp); int main() { int num_of_emp; printf("Enter the number of employees: "); scanf("%d", &num_of_emp); getchar(); // 清空输入缓冲区的换行符 // 正确分配结构体数组内存 struct emp_details* employees_data = malloc(num_of_emp * sizeof(struct emp_details)); if(employees_data == NULL) { printf("Memory allocation failed!\n"); return 1; } for(int i=0; i<num_of_emp; i++) { employees_data[i].name = malloc(30 * sizeof(char)); printf("Employee %d enter the Name: ", i+1); fgets(employees_data[i].name, 30, stdin); employees_data[i].name[strcspn(employees_data[i].name, "\n")] = '\0'; employees_data[i].address = malloc(100 * sizeof(char)); printf("Employee %d enter the Address: ", i+1); fgets(employees_data[i].address, 100, stdin); employees_data[i].address[strcspn(employees_data[i].address, "\n")] = '\0'; employees_data[i].Emp_ID = malloc(10 * sizeof(char)); printf("Employee %d enter the Employee ID: ", i+1); fgets(employees_data[i].Emp_ID, 10, stdin); employees_data[i].Emp_ID[strcspn(employees_data[i].Emp_ID, "\n")] = '\0'; printf("Employee %d enter the Age: ", i+1); scanf("%d", &employees_data[i].age); getchar(); // 清空输入年龄后的换行符 } printf("\n\tEmployee details before sorting\n"); for(int i=0; i<num_of_emp; i++) { printf("Employee %d Name: %s\n", i+1, employees_data[i].name); printf("Employee %d Address: %s\n", i+1, employees_data[i].address); printf("Employee %d Age: %d\n", i+1, employees_data[i].age); printf("Employee %d ID: %s\n\n", i+1, employees_data[i].Emp_ID); } ascen_str(employees_data, num_of_emp); // 释放所有动态分配的内存 for(int i=0; i<num_of_emp; i++) { free(employees_data[i].name); free(employees_data[i].address); free(employees_data[i].Emp_ID); } free(employees_data); return 0; } void ascen_str(struct emp_details* employees_data, int num_of_emp) { struct emp_details temp; for (int i = 0; i < num_of_emp; i++) { for (int j = i + 1; j < num_of_emp; j++) { if (strcmp(employees_data[i].name, employees_data[j].name) > 0) { temp = employees_data[i]; employees_data[i] = employees_data[j]; employees_data[j] = temp; } } } printf("\n\tEmployee details in ascending order by name\n"); for (int i = 0; i < num_of_emp; i++) { printf("Employee Name: %s\n", employees_data[i].name); printf("Employee Address: %s\n", employees_data[i].address); printf("Employee Age: %d\n", employees_data[i].age); printf("Employee ID: %s\n\n", employees_data[i].Emp_ID); } }
内容的提问来源于stack exchange,提问作者Balaji Baski
相关产品推荐
相关产品推荐

