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

C语言如何正确获取指针结构体字段值并为字段赋值

问题原因

你的代码存在3个核心错误,直接触发编译报错、值读取异常:

  • 赋值逻辑完全违背指针规则:&(p1->state) 取的是state指针成员自身的内存地址,属于结构体内部的固定偏移值,是只读右值,根本不能放在等号左侧被赋值,和写&a = 10报错的原理完全一致。
  • 指针成员未指向合法内存:state本身是int*类型(指向int的指针),直接给它赋整数值20,本质是把内存地址0x14硬塞给指针,后续访问属于野指针操作,触发未定义行为。
  • 传参类型和printf占位符不匹配:打印时传&p1->state拿到的是state成员的地址,类型为int**,和%d要求的int类型完全不匹配,输出值完全不可控。
  • 补充缺失依赖:原代码未引入stdlib.h头文件,会导致malloc隐式声明报错。
修正方案

根据实际使用场景选对应写法即可:

场景1:需要动态存储state的值

给指针成员单独申请对应类型的内存,再读写值,是工程中最常用的写法:

#include <stdio.h>
#include <stdlib.h>

typedef struct Player
{
    int *state;
} Player;


int main(int argc, char* argv[]) {
    Player *p1;
    p1 = malloc(sizeof(Player));
    // 检查内存分配是否成功
    if (p1 == NULL) {
        return 1;
    }

    // 给state指针申请一块能存int的合法内存
    p1->state = malloc(sizeof(int));
    if (p1->state == NULL) {
        free(p1); // 释放已申请的结构体内存,避免泄漏
        return 1;
    }
    // 给state指向的内存空间写入值20
    *(p1->state) = 20;
    // 解引用读取state指向的实际值,和%d占位符类型匹配
    printf("player state = %d\n", *(p1->state));

    // 按申请逆序释放内存:先释放内部成员的动态内存,再释放结构体本身
    free(p1->state);
    free(p1);
    return 0;
}

场景2:state仅需指向已存在的变量

如果不需要动态管理state的生命周期,直接让指针指向栈上已定义的int变量即可,写法更简洁:

#include <stdio.h>
#include <stdlib.h>

typedef struct Player
{
    int *state;
} Player;


int main(int argc, char* argv[]) {
    Player *p1;
    p1 = malloc(sizeof(Player));
    if (p1 == NULL) {
        return 1;
    }

    int val = 20;
    p1->state = &val; // 直接让state指向栈上已存在的val变量
    printf("player state = %d\n", *(p1->state));

    free(p1); // 栈上val不需要手动释放
    return 0;
}
关键注意点
  • 取地址符&拿到的值是右值,只能读不能被赋值
  • 所有指针类型的变量,必须先指向一块合法、类型匹配的内存,才能通过解引用符*读写对应内存的内容
  • printf的格式化占位符必须和传入参数的类型严格匹配,否则会出现输出错乱、程序崩溃等问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 11:36:21