C语言结构体指针赋值出现段错误,求正确实现方法
结构体中char指针成员赋值导致段错误的解决方法
问题描述
初学C/C++时,使用包含char指针成员的结构体,给结构体数组元素的char指针赋值时出现段错误,最初用scanf也有同样问题,不确定是语法还是指针使用错误,想了解正确的结构体指针赋值与访问方法。
定义的结构体
typedef struct student_info { char *first; char *last; int exam1; int exam2; int exam3; float mean; } student;
测试代码
#include <iostream> #include <stdio.h> #include <stdlib.h> #include <string.h> using namespace std; #include "student.h" #include "bubble.h" int main() { //Initial Variable Declaration student students[19]; //Read recurring student info from 'grades' for (int i = 0; i < 19; ++i)//check if the loop has to occur dynamically { //Read first name & last name cin >> *(students[i].first) >> *(students[i].last); } //Output read data to test //Output recurring data for (int i = 0; i < 19; ++i) { //Output first and last name ending with a tab //cout << students[i].first << "\t" << students[i].last << "\t"; } return 0; }
错误原因
- 野指针问题:结构体里的
char *first和char *last只是指针,声明结构体数组后,这些指针没有被初始化,属于野指针(指向随机的无效内存地址),直接赋值会非法访问内存,触发段错误。 - 语法使用错误:
cin >> *(students[i].first)这种写法完全错误——cin读取字符串需要的是char数组首地址或已分配内存的char指针,你解引用指针(*)后得到的是单个char,只能存一个字符,根本没法读取完整名字。
两种正确解决方法
方法1:用固定大小char数组替代指针
把结构体中的char指针改成固定长度的数组,声明结构体时会自动分配内存,简单直接:
typedef struct student_info { char first[50]; // 假设名字最长不超过49个字符,可按需调整 char last[50]; int exam1; int exam2; int exam3; float mean; } student;
读取时直接用数组名(数组名本身就是首地址):
cin >> students[i].first >> students[i].last;
方法2:手动为char指针分配内存
如果必须用指针,要先通过malloc或new分配足够内存,再读取字符串:
for (int i = 0; i < 19; ++i) { // 分配内存,每个名字最多存50个字符 students[i].first = (char*)malloc(50 * sizeof(char)); students[i].last = (char*)malloc(50 * sizeof(char)); // 检查内存分配是否成功(可选但推荐) if (students[i].first == NULL || students[i].last == NULL) { perror("malloc failed"); exit(1); } // 直接用指针读取字符串,不需要解引用 cin >> students[i].first >> students[i].last; }
注意:使用完内存后要释放,避免内存泄漏:
for (int i = 0; i < 19; ++i) { free(students[i].first); free(students[i].last); }
如果是C++,也可以用new char[50]分配,delete[]释放。
补充:scanf的正确用法
用scanf读取时,同样要传指针(数组首地址或已分配内存的指针):
- 数组场景:
scanf("%s %s", students[i].first, students[i].last); - 动态分配指针场景:
scanf("%s %s", students[i].first, students[i].last);
内容的提问来源于stack exchange,提问作者Noah Stromberg
相关产品推荐
相关产品推荐

