类所占内存空间总结

本文详细解析了C++中类的大小如何计算,包括空类、含有不同类型的成员变量及虚函数的类,并讨论了继承对类大小的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

C++中的

 最近在复习c++的一些基础,感觉这篇文章很不错,转载来,大家看看!

类所占内存的大小是由成员变量(静态变量除外)决定的,成员函数(这是笼统的说,后面会细说)是不计算在内的。

摘抄部分:

成员函数还是以一般的函数一样的存在。a.fun()是通过fun(a.this)来调用的。所谓成员函数只是在名义上是类里的。其实成员函数的大小不在类的对象里面,同一个类的多个对象共享函数代码。而我们访问类的成员函数是通过类里面的一个指针实现,而这个指针指向的是一个table,table里面记录的各个成员函数的地址(当然不同的编译可能略有不同的实现)。所以我们访问成员函数是间接获得地址的。所以这样也就增加了一定的时间开销,这也就是为什么我们提倡把一些简短的,调用频率高的函数声明为inline形式(内联函数)。

(一)
class CBase 

}; 
sizeof(CBase)=1;

为什么空的什么都没有是1呢?
c++要求每个实例在内存中都有独一无二的地址。//注意这句话!!!!!!!!!!
空类也会被实例化,所以编译器会给空类隐含的添加一个字节,这样空类实例化之后就有了独一无二的地址了。所以空类的sizeof为1。

(二)

class CBase 

int a; 
char p; 
}; 
sizeof(CBase)=8;
记得对齐的问题int 占4字节//注意这点和struct的对齐原则很像!!!!!
char占一字节,补齐3字节

(三)
class CBase 

public: 
CBase(void); 
virtual ~CBase(void); 
private: 
int  a; 
char *p; 
}; 
再运行:sizeof(CBase)=12

C++ 类中有虚函数的时候有一个指向虚函数的指针(vptr),在32位系统分配指针大小为4字节。无论多少个虚函数,只有这一个指针,4字节。//注意一般的函数是没有这个指针的,而且也不占类的内存。

(四)
class CChild : public CBase 

public: 
CChild(void); 
~CChild(void); 

virtual void test();
private: 
int b; 
}; 
输出:sizeof(CChild)=16;
可见子类的大小是本身成员变量的大小加上父类的大小。//其中有一部分是虚拟函数表的原因,一定要知道

父类子类共享一个虚函数指针

(五)

#include<iostream.h>

class a {};

class b{};

class c:public a{

virtual void fun()=0;

};

class d:public b,public c{};

int main()

{

cout<<"sizeof(a)"<<sizeof(a)<<endl;

cout<<"sizeof(b)"<<sizeof(b)<<endl;

cout<<"sizeof(c)"<<sizeof(c)<<endl;

cout<<"sizeof(d)"<<sizeof(d)<<endl;

return 0;}

程序执行的输出结果为:

sizeof(a) =1

sizeof(b)=1

sizeof(c)=4

sizeof(d)=8

前三种情况比较常见,注意第四种情况。类d的大小更让初学者疑惑吧,类d是由类b,c派生迩来的,它的大小应该为二者之和5,为什么却是8 呢?这是因为为了提高实例在内存中的存取效率.类的大小往往被调整到系统的整数倍.并采取就近的法则,里哪个最近的倍数,就是该类的大小,所以类d的大小为8个字节.

总结:

空的类是会占用内存空间的,而且大小是1,原因是C++要求每个实例在内存中都有独一无二的地址。

(一)类内部的成员变量:

  • 普通的变量:是要占用内存的,但是要注意对齐原则(这点和struct类型很相似)。
  • static修饰的静态变量:不占用内容,原因是编译器将其放在全局变量区。

(二)类内部的成员函数:

  • 普通函数:不占用内存。
  • 虚函数:要占用4个字节,用来指定虚函数的虚拟函数表的入口地址。所以一个类的虚函数所占用的地址是不变的,和虚函数的个数是没有关系的
  • 说明:此博文转载之http://blog.sina.com.cn/s/blog_69c189bf0100mkeu.html

<think>好的,我现在要回答用户关于指针在不同系统架构下内存占用的问题。首先,我需要明确指针的基本概念。指针本质上是一个变量,其值是另一个变量的内存地址。因此,指针的大小取决于系统能够寻址的内存空间有多大。 接下来,我需要回忆一下不同位数的系统架构对寻址能力的影响。32位系统的CPU寄存器通常是32位宽,这意味着它可以处理的最大内存地址是2的32次方,也就是4GB。因此,32位系统的指针需要4个字节来存储地址,这样就能覆盖所有的内存地址。例如,在32位的Windows或Linux系统中,无论是哪种型的指针(比如int*、char*),它们本身占用的内存都是4字节[^1]。 然后是64位系统。64位系统的寄存器宽度增加到64位,因此可以寻址的内存空间大大增加,达到2的64次方,这个数值远远超过实际物理内存的大小。因此,64位系统的指针需要8个字节来存储地址。比如在64位的操作系统下,一个指针变量如void*或任何其他型的指针都会占用8字节的内存空间[^1]。 不过,这里可能有一些特殊情况需要考虑。比如在某些嵌入式系统或特定的微控制器架构中,可能存在非标准的指针大小。例如,STM32系列基于ARM Cortex-M处理器,通常是32位架构,因此指针大小为4字节。根据参考中的引用[2],STM32F103的RAM和Flash配置不同,但指针大小仍然由处理器架构决定,而不是内存容量。因此,即使在资源受限的嵌入式系统中,只要处理器是32位的,指针仍占4字节。 另外,用户提到的结构体内存对齐问题也相关。比如在64位系统中,结构体的对齐方式可能影响整体大小,但每个指针成员自身仍占8字节。例如,一个结构体包含一个char和一个指针,由于对齐,结构体大小可能会是16字节(char占1字节,填充7字节,指针8字节)[^1]。 总结起来,指针的大小主要由系统架构决定:32位系统4字节,64位系统8字节。特殊情况如嵌入式系统需具体分析,但通常遵循架构位数。需要确保用户理解位数与寻址能力的关系,以及内存对齐可能带来的影响。</think>### 指针在不同系统架构下的内存占用分析 1. **指针的本质与系统架构的关系** 指针是存储内存地址的变量,其占用空间大小由系统架构的寻址能力决定。 - **32位系统**:最大寻址空间为 $2^{32} = 4\ \text{GB}$,因此指针需要 **4字节(32位)** 存储地址。 - **64位系统**:最大寻址空间为 $2^{64}$,远超物理内存需求,因此指针需要 **8字节(64位)** 存储地址。 2. **具体场景验证** - **C/C++ 示例**: ```c printf("指针大小:%zu字节\n", sizeof(void*)); // 32位系统输出4,64位系统输出8 ``` - **嵌入式系统**(如STM32): 基于32位ARM架构(如STM32F103),指针占用 **4字节**,与其Flash和RAM容量无关[^2]。 3. **内存对齐的影响** 在结构体中,指针的占用可能因对齐规则被放大。例如64位系统中: ```c struct Example { char c; // 1字节 void* ptr; // 8字节(实际占用16字节,因对齐需填充7字节) }; ``` 结构体总大小为 $1 + 7\ \text{(填充)} + 8 = 16\ \text{字节}$。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值