You need to enable JavaScript to run this app. C++类成员函数内存分配规则与sizeof统计逻辑解析
优惠活动
大模型
产品
解决方案
定价
更多

C++类成员函数内存分配规则与sizeof统计逻辑解析

C++类内存布局问题解析

为什么sizeof计算类大小时,不将类内定义的普通成员函数纳入统计?

首先要明确一个核心前提:sizeof(类)的统计对象,是该类创建单个独立实例时,需要为这个实例分配的专属内存空间大小,本质是衡量单个对象的内存开销,而非汇总类关联的所有代码、符号的总体积。

普通非静态成员函数从设计上就和单个对象的内存完全解耦,这也是它不被计入实例大小的根本原因:

  • 同一类的所有实例,调用的都是完全相同的一份函数指令代码,完全没有必要为每个对象单独拷贝一份重复的函数实现,否则会造成无意义的内存浪费。
  • 普通成员函数经过编译后,会被转换为一个带隐含this指针参数的全局函数。所有对象调用成员函数时,只是把自身的内存地址作为this参数传入,跳转执行同一份全局指令,根本不需要把函数代码存储到每个对象的内存块里。

编译阶段的实际转换逻辑可以参考下面的示意:

// 原代码中的成员函数 getData()
// 编译后会被隐式转换为带this参数的全局函数
void item_getData(item* this_ptr) {
    cin >> this_ptr->cost;
    cin >> this_ptr->price;
}
// 所有形如 obj.getData() 的调用,编译后都会被替换为 item_getData(&obj)

回到示例中的item类,因为它没有定义虚函数、也没有需要额外对齐的特殊成员,sizeof统计的就只有两个非静态成员变量——4字节的int cost、4字节的float price,刚好凑出8字节的计算结果,和实际运行输出完全一致。
这里补充一个容易混淆的场景:如果类定义了虚函数,实例内存中会额外增加一个虚表指针的大小(主流64位平台下占8字节),但这部分空间只是存储类虚表的入口地址,存储的依然是地址值,并不是把虚函数的代码本身算到实例大小里。

示例中的getData成员函数实际占多少内存、存储在哪个内存区域?

  • 实际内存大小:getData函数本身的内存占用,就是它经过编译后生成的可执行机器指令的总字节数,没有固定的通用值——具体大小取决于函数内的逻辑复杂度、编译器的优化等级,比如两次cin读值的逻辑生成的汇编指令,通常是几十到上百字节不等。这部分内存完全不属于任何item类实例的专属内存,自然也不会参与实例大小的计算。
  • 内存分配区域:这类函数的可执行指令,会被加载到进程地址空间的代码段(又称文本段),这个段是程序启动加载时就被映射的只读、可执行内存区域,所有调用该函数的逻辑,不管是哪个item对象触发的,最终都会跳转到代码段中同一份指令位置执行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.31 10:06:03