C语言使用结构体、指针开发学生链表时打印字符串出现乱码求助
乱码问题的核心根源
你遇到的字符串乱码,本质不是结构体的char*没有分配内存,而是存储的指针已经失效:
- 在
enrolStudent函数中定义的last[15]、first[15]、course[15]是栈上的局部数组,函数执行结束后,这些数组占用的栈内存会被系统回收,后续可被其他栈操作覆盖。 - 你在
createStudent里只是把这些临时数组的首地址直接赋值给了结构体的字符指针,没有把字符串内容做持久化存储。等enrolStudent函数返回后,结构体里的指针指向的已经是被覆盖的无效内存,打印时自然出现乱码。
正确的内存分配实现方式
要让字符串内容和Student结构体的生命周期绑定,需要主动给字符串分配堆内存,将字符串内容完整复制过去,而不是直接存临时指针的地址。
第一步:引入依赖头文件
需要在代码顶部增加<string.h>头文件,提供strlen、strcpy等字符串操作函数的声明:
#include <string.h>
第二步:修改createStudent的字符串赋值逻辑
替换原来直接给字符指针赋值的代码,按照「计算字符串长度 → 分配堆内存 → 复制字符串内容」的流程处理:
// 原有代码的替代部分 // 为last姓名成员分配独立堆内存 student->last = (char *)malloc(strlen(last) + 1); strcpy(student->last, last); // 为first姓名成员分配独立堆内存 student->first = (char *)malloc(strlen(first) + 1); strcpy(student->first, first); // 为course课程成员分配独立堆内存 student->course = (char *)malloc(strlen(course) + 1); strcpy(student->course, course);
这里给长度加1是为了预留C字符串必须的结束符\0的存储位置,避免出现字符串识别越界的问题。
第三步:补充配套的内存释放逻辑
因为现在三个字符串成员是独立在堆上分配的,后续你从链表中移除学生节点、或者程序结束销毁整个链表时,需要先对每个学生节点的三个字符串指针调用free释放堆内存,再释放Student结构体本身的内存,否则会造成堆内存泄漏。
代码中连带需要修复的其他隐患
- 目前的
scanf("%s", last)这类输入没有长度限制,如果用户输入超过14个字符(对应数组长度15,需留1个位置给字符串结束符),会造成栈溢出。可以修改为带长度限制的输入格式,比如scanf("%14s", last)。 - 现有链表插入逻辑存在断点:当插入的index既不是链表头(index=0)也不是链表尾(index=list->size)时,没有处理前后节点的指针链接,插入的节点不会真正接入链表,后续需要补充这个分支的指针操作逻辑。
内容的提问来源于stack exchange,提问作者Kyle Angelo Gonzales
相关产品推荐
相关产品推荐

