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
相关产品推荐
相关产品推荐

