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

为何p->p1输出1而s2.p1输出0?结构体复制后表现差异问询

问题分析:结构体赋值后的成员差异原因

首先直接给结论:这是因为结构体赋值是值拷贝操作,*p = s2; 之后,p指向的堆内存结构体和栈上的s2是完全独立的两个实例,修改其中一个的成员不会影响另一个。你看到的差异完全符合预期,而p->p2和s2.p2没有差异,只是因为你没修改s2.p2而已。

详细拆解代码执行流程

  • 结构体初始化:

    struct S2 s2 = {1,2,3,0};
    

    根据struct S2的成员顺序(int p1; struct S1 s1; int p2;),这个初始化会完成以下赋值:

    • s2.p1 = 1
    • s2.s1.p1 = 2
    • s2.s1.p2 = 3
    • s2.p2 = 0
  • 内存分配与结构体拷贝:

    // 注意:原代码里写的是struct s2(小写),这是语法错误,C语言大小写敏感,应改为struct S2
    p = (struct S2 *)malloc(sizeof(struct S2));
    *p = s2;
    

    malloc在堆上分配了一块与struct S2大小一致的内存,*p = s2执行的是完整的值拷贝:把s2的所有成员变量的值,逐一复制到p指向的堆内存区域。此时,堆上的结构体和栈上的s2是完全独立的两个实体,拥有不同的内存地址,修改其中一个的成员变量,不会对另一个产生任何影响。

  • 修改s2的p1成员:

    s2.p1 = 0;
    

    这行代码仅修改了栈上s2结构体的p1成员,堆上p指向的结构体的p1成员依然保留拷贝时的原值1,所以后续打印会出现p->p1=1、s2.p1=0的差异。

  • 为什么p->p2和s2.p2没有差异?
    原因很简单:你从始至终都没有修改过s2.p2的值,它从初始化后一直是0;而p->p2在拷贝时也继承了这个0,所以两者的值自然相同。如果你添加一行s2.p2 = 5;,再打印两个值,就会看到p->p2还是0,s2.p2变成5,和p1的表现完全一致。

代码里的小错误提醒

原代码中malloc的强制类型转换写了struct s2(小写),C语言是大小写敏感的,编译器会认为s2是未定义的结构体类型,导致编译报错,应该修正为struct S2。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:23:42