C语言void*存储int时结构体值未生效,如何修改void指针指向的值
问题原因
你的代码核心错误出在student_create函数的赋值逻辑:
- 你先为
new_student->grade申请了堆内存,紧接着直接将grade指针赋值为形参x的地址,直接覆盖了刚申请的堆内存地址,既造成内存泄漏,又引入了野指针风险 - 形参
x是函数内的局部变量,存储在栈内存中,student_create执行结束后对应的栈空间会被系统回收复用。多次调用该函数时,形参x的栈地址是相同的,最后一次调用传入的数值是7,因此所有student的grade指针最终都指向同一个存着7的栈地址,读取时全部返回7。
修复方案
保持grade为void*类型的前提下,只需要修改student_create函数的赋值逻辑,把形参x的值拷贝到你申请的堆内存中,不要修改grade指针本身的指向即可:
student *student_create(int x){ student *new_student = malloc(sizeof(student)); new_student->grade = malloc(sizeof(int)); // 把x的值写入申请的堆内存,而非让grade指向栈地址 *(int *)new_student->grade = x; return new_student; }
修复后程序运行输出的最后三行就会符合预期:2、4、7,后续你调用student_inc修改成绩的逻辑也可以正常生效,堆内存会一直有效直到你主动释放。
额外优化建议
- 你
school_create函数的形参名school_szie是拼写错误,建议修正为school_size避免后续维护出错 - 程序退出前建议补充内存释放逻辑,依次释放每个
student的grade成员、每个student实例、students数组、school实例,避免内存泄漏。
内容的提问来源于stack exchange,提问作者JackNewman
相关产品推荐
相关产品推荐

