You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 17:10:20