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

指针数组首行打印异常求助:结构体读取数据文件问题排查

问题分析与修复方案

1. 首行乱码/垃圾值的根源与修复

你的代码存在严重的内存越界访问,这是触发乱码和未定义行为的核心原因:

  • 你为studentDataBase的每行仅分配了6个student*的存储空间(malloc(6*sizeof(student*))),但后续循环给第0行的studentDataBase[0][i]赋值时,i的范围是0到18(共19个元素),远超每行6个的容量,直接非法访问堆内存,破坏内存结构,导致乱码和垃圾数值。
  • 同时,循环for(int j=1;j<studentcount;j++)将studentDataBase[0][i]赋值给studentDataBase[j][i]时,i同样超出每行6个元素的范围,进一步加剧内存越界问题。

修复方式

当前三维数组的设计冗余且逻辑混乱,若仅需存储一组学生数据,直接简化为一维指针数组即可:

// 替换原三维数组定义
student** studentData;

// 在main中分配内存
studentData = (student**)malloc(studentcount * sizeof(student*));
for(int i=0; i<studentcount; i++){
    studentData[i] = NULL;
}

随后将所有studentDataBase[0][i]替换为studentData[i],删除多余的行复制逻辑(若无需多份数据副本)。

2. 内存泄漏的修复

当前代码仅释放了顶层的studentDataBase指针,完全未释放下层内存块,需按从底层到顶层的顺序逐层释放:

正确释放流程(针对简化后的一维数组)

  1. 遍历每个学生结构体,先释放first和last字符串
  2. 释放学生结构体本身
  3. 释放顶层的指针数组

示例代码:

// 逐层释放内存
for(int i=0; i<studentcount; i++){
    free(studentData[i]->first);
    free(studentData[i]->last);
    free(studentData[i]);
}
free(studentData);

若坚持使用原三维数组设计,需先遍历所有有效行和列,释放每个学生的字符串和结构体,再释放每行的指针数组,最后释放顶层数组。

修复后的完整代码

#include <stdio.h>
#include <stdlib.h>
#include "student.h"
#include "bubble.h"
#include <string.h>
#include <assert.h>

void printStudent(student *studentData)
{
    printf("%s, %s: %d, %d, %d\n", 
            studentData->last,
            studentData->first,
            studentData->exam1,
            studentData->exam2,
            studentData->exam3);
}

void printData(student *students[], int studentcount)
{
    int i;
    for(i=0;i<studentcount;i++)
        printStudent(students[i]);
}

int main()
{
    int studentcount = 19;
    char className[10];
    char tempFirst[50];
    char tempLast[50];

    scanf("%s", className); 
    printf("%s\n", className);

    // 简化为一维指针数组存储学生数据
    student** studentData = (student**)malloc(studentcount * sizeof(student*));
    for(int i=0; i<studentcount; i++){
        studentData[i] = NULL;
    }

    for(int i=0;i<studentcount;i++) 
    {
        studentData[i] = (student*)malloc(sizeof(student));
        scanf("%s %s %d %d %d"
              ,tempFirst, tempLast
              ,&studentData[i]->exam1, &studentData[i]->exam2, 
              &studentData[i]->exam3);
        
        studentData[i]->first = (char*)malloc(strlen(tempFirst)+1);
        strcpy(studentData[i]->first, tempFirst);
        studentData[i]->last = (char*)malloc(strlen(tempLast)+1);
        strcpy(studentData[i]->last, tempLast);
    }

    printData(studentData, studentcount);

    // 逐层释放内存
    for(int i=0; i<studentcount; i++){
        free(studentData[i]->first);
        free(studentData[i]->last);
        free(studentData[i]);
    }
    free(studentData);

    return 0;
}

额外注意事项

  • 确保student.h中的student结构体包含char* first、char* last、int exam1、int exam2、int exam3字段
  • 使用scanf读取字符串时,建议用%49s限制长度,避免缓冲区溢出
  • 可添加空指针检查(如assert(studentData[i] != NULL)),确保malloc调用成功

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 16:51:33