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

为何使用箭头操作符可写入动态分配结构体成员却无法读取?

问题分析与修复方案

你的代码出现读取异常主要有两个关键问题:

1. 指针偏移导致非法内存访问

第一个循环中,你每次迭代都执行memptr++,当循环结束时,memptr已经指向malloc分配的结构体数组末尾之外的内存地址。第二个打印循环继续执行memptr++,相当于完全在非法内存区域读取数据,自然无法显示正确内容。

解决方法:保存初始指针,或者改用数组下标访问,避免修改原始指针的位置。

2. 成员类型不匹配导致写入错误

结构体中Comments是int Comments[100]类型,但你用fgets(memptr->Comments, 100, stdin)写入——fgets的第一个参数要求是char*,直接传入int数组会导致类型不匹配,内存写入混乱,后续读取时也会因为类型错误输出异常。

解决方法:如果要存储字符串,把Comments的类型改成char Comments[100];如果确实需要存储整数,应该用循环读取int值的方式,而非fgets。


修复后的完整代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct {
    int RollNo;
    char Name[15];
    int Class;
    int Marks;
    char Comments[100]; // 修改为char数组适配字符串存储
} details;

int main()
{
    int n, i, j;
    printf("Enter number of students\n");
    if (scanf("%d", &n) != 1) {
        perror("Invalid Input");
        return 1;
    }
    details *memptr = malloc(n * sizeof(details));
    if (memptr == NULL) {
        perror("Memory not allocated successfully!!");
        return 1;
    }

    // 用下标访问,不修改原始指针memptr的位置
    for (i = 0; i < n; i++) {
        printf("Enter RollNo: ");
        scanf("%d%*c", &(memptr[i].RollNo));
        printf("Enter Name: ");
        fgets(memptr[i].Name, 15, stdin);
        // 去除fgets读取的换行符,避免输出冗余空行
        memptr[i].Name[strcspn(memptr[i].Name, "\n")] = '\0';
        printf("Enter Class: ");
        scanf("%d%*c", &(memptr[i].Class));
        printf("Enter Marks: ");
        scanf("%d%*c", &(memptr[i].Marks));
        printf("Enter Comments: ");
        fgets(memptr[i].Comments, 100, stdin);
        memptr[i].Comments[strcspn(memptr[i].Comments, "\n")] = '\0';
        printf("\n");
    }

    printf("Student details\n\n");
    // 同样用下标访问初始指针指向的数组
    for (j = 0; j < n; j++) {
        printf("RollNo: %d ", memptr[j].RollNo);
        printf("Name: %s ", memptr[j].Name);
        printf("Class: %d ", memptr[j].Class);
        printf("Marks %d ", memptr[j].Marks);
        printf("Comments: %s\n", memptr[j].Comments);
    }

    free(memptr); // 释放动态分配的内存,避免泄漏
    return 0;
}

额外说明:修复代码中加入了strcspn去除fgets读取的换行符,优化输出格式;同时新增free(memptr),规范内存管理。

内容的提问来源于stack exchange,提问作者IndyRose

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 05:25:19