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

C语言被调用函数内的结构体变量:应使用指针还是无差异?

C语言结构体变量的内存分配与声明机制解析

函数内两种声明方式的核心差异

先明确示例中两行代码的本质区别:

  • MyInnerStruct something = some_ptr->some;:这是值拷贝操作。函数栈上会分配一块与MyInnerStruct总大小(含对齐填充)一致的内存,然后把some_ptr->some的所有成员数据完整复制到这块新内存中。后续对something的修改只会影响栈上的副本,和传入的原结构体毫无关联。
  • MyInnerStruct* something = &some_ptr->some;:这是创建指针引用。something本身是一个指针变量(在栈上占用指针大小的内存,32位系统为4字节,64位为8字节),它指向的是原结构体some_ptr中some成员的内存地址。后续通过something访问或修改的都是原结构体里的目标成员,不会产生任何拷贝操作。

显然,这两种声明方式完全不等价。

函数内结构体变量的内存分配逻辑

函数内与全局结构体的内存分配核心规则一致,仅存储区域不同:

  • 全局/静态结构体变量:分配在全局数据区,内存会预留结构体总大小(含对齐填充)的空间,程序启动时自动初始化(未显式初始化则默认清零)。
  • 函数内的局部结构体变量(如第一行的something):分配在函数调用时生成的栈帧上,大小为结构体总大小(含对齐填充),函数返回时栈帧销毁,对应内存被释放。
  • 函数内的指针变量:不管指向何种类型,本身仅占用指针大小的栈内存,它指向的内存位置由赋值的地址决定(示例中指向的是调用者传入结构体的成员地址,该地址可能属于栈、堆或全局区)。

不复制原结构体元素的正确方式

如果仅需访问传入原结构体的对应元素,且不想产生拷贝开销,必须使用第二种指针声明方式:

MyInnerStruct* something = &some_ptr->some;

这种方式下,后续通过something->b访问的就是原结构体中的b成员,修改操作也会直接作用于原结构体。对于包含大量成员、嵌套结构体或指针的复杂结构体,这种方式能避免不必要的内存占用和性能损耗。

补充:函数参数传递的内存差异

你提到的直接传MyStruct与传指针的区别也需要明确:

  • 传值:函数参数会在栈上分配一块与MyStruct总大小一致的内存,将调用者的结构体内容完整拷贝进去。函数内对参数的修改仅影响副本,原结构体不受影响,且大结构体传值会带来明显的内存开销和拷贝耗时。
  • 传指针:参数仅占用指针大小的栈内存,传递的是原结构体的起始地址,函数内通过指针直接操作原结构体的内存,无拷贝开销,效率更高。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 02:16:18