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

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;
}

错误原因

  1. 野指针问题:结构体里的char *first和char *last只是指针,声明结构体数组后,这些指针没有被初始化,属于野指针(指向随机的无效内存地址),直接赋值会非法访问内存,触发段错误。
  2. 语法使用错误: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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 15:42:49