
目录常规类型union联合体struct结构体class占用综合尝试存储单位换算1 字节 1 byte 8 位 8 bit常规类型指针是一个uintptr_t其所占内存字节一般是和计算机的CPU字长是一致的64位系统指针所占的内存空间一般为8个字节32位系统指针所占的内存空间一般为4个字节不论char *还是int *亦或是float *。char *p 是一个指针它保存的内容是一个地址指向(*p)而*p)才是那个字节。intn10;// 4chars1[]Hello;// 6chars2[100]0123456789;// 100char*p1s1;// 864位系统void*p2malloc(100);// 864位系统int*pint;char*p111;// 8、864位系统数组是函数的形参时会降为指针故func1传入的p仍然是原指针p的拷贝也是一个指针voidfunc1(charp[100])//func1的p也是跟指针一样的字节数{std::coutsizeof(p)std::endl;// 864位系统}voidfunc2(char(p)[10])// p是装10个char类型数据的数组的引用其结果类似于char p[10]; std::cout sizeof(p);{std::coutsizeof(p)std::endl;// 10}voidfunc3(doubleb)// 引用没啥好说的{std::coutsizeof(b)std::endl;// 8}union联合体union的大小取决于它所有的成员中占用空间最大的一个成员的大小并且需要内存对齐所以以下显而易见。unionUn1{inta;doubleb;charc;// sizeof(Un1) sizeof(double) 8};unionUn2{charbuffer[13];// sizeof(Un2) sizeof(buffer) 13};区别来了下面Un3、Un4默认下内存size分别为13、16。unionUn3{charbuffer[13];charc;};unionUn4{charbuffer[13];intnumber;//由于int类型成员的存在使u2的对齐方式变成4也就是说u2的大小必须在4的对界上所以占用的空间变成了16最接近13的对界};升级难度猜猜下面union分别在#pragma pack(1) 、#pragma pack(2) 、#pragma pack(4) 、#pragma pack(8) 下内存sizeunionUn4{charbuffer[13];intnumber;};揭晓答案分别是13、14、16、16。struct结构体struct就是一些元素的集合它们在内存中的存放是有先后顺序的并且每个元素都有自己的内存空间。structss1{charc;// [0]....[3]inti;// [4]....[7]};// sizeof(ss1) 8structss2{};// sizeof(ss2) 1,与下面空类也占用1个字节的原因一致内存对齐规则参考内存对齐1、内存对齐2结构体中成员的顺序直接影响内存空洞的大小错误的排序可能导致大量内存浪费如下。structBadOrder{chara;// 1字节偏移0doubleb;// 8字节对齐需偏移8补7字节空洞intc;// 4字节对齐偏移8816chard;// 1字节偏移16420};// 总大小20121需满足最大对齐值8补3字节空洞总大小24structGoodOrder{doubleb;// 8字节偏移0intc;// 4字节偏移8chara;// 1字节偏移12chard;// 1字节偏移13};// 总大小13114需满足最大对齐值8补2字节空洞总大小16可借助offsetof算出偏移#includeiostreamstructBadOrder{chara;doubleb;intc;chard;};structGoodOrder{doubleb;intc;chara;chard;};intmain(){std::coutBadOrder: sizeof(BadOrder)std::endl;std::coutOffset of a: offsetof(BadOrder,a)std::endl;std::coutOffset of b: offsetof(BadOrder,b)std::endl;std::coutOffset of c: offsetof(BadOrder,c)std::endl;std::coutOffset of d: offsetof(BadOrder,d)std::endl;std::coutGoodOrder: sizeof(GoodOrder)std::endl;std::coutOffset of a: offsetof(GoodOrder,a)std::endl;std::coutOffset of b: offsetof(GoodOrder,b)std::endl;std::coutOffset of c: offsetof(GoodOrder,c)std::endl;std::coutOffset of d: offsetof(GoodOrder,d)std::endl;return0;}class占用一个Class对象占用内存空间为: 非静态成员变量总和 数据对齐处理 虚函数。也就是说静态成员数据不做考虑。普通成员函数是针对类体的成员函数的大小不在类的对象里面同一个类的多个对象共享函数代码共用相同的函数指针所以自然不能归为实例的大小。而析构函数跟构造函数这些成员函数是跟sizeof无关的也不难理解因为我们的sizeof是针对实例。我们访问类的成员函数是通过类里面的一个指针实现而这个指针指向的是一个tabletable里面记录的各个成员函数的地址。所以我们访问成员函数是间接获得地址的这样也就增加了一定的时间开销所以提倡把一些简短的调用频率高的函数声明为inline形式内联函数。#includeiostreamclassA{};//c要求每个实例在内存中都有独一无二的地址!!!!! 空类也会被实例化//所以编译器会给空类隐含的添加一个字节这样空类实例化之后就有了独一无二的地址了。所以空类的sizeof为1。classB{public:B(){}virtual~B(){}//每个实例都有虚函数表//C 类中有虚函数的时候有一个指向虚函数的指针vptr在32位系统分配指针大小为4字节。//无论多少个虚函数只有这一个指针4字节。//注意一般的函数是没有这个指针的而且也不占类的内存。voidaa(){}//普通成员函数为各实例公有不归入sizeof统计virtualvoidB1(){}//虚函数记入sizeof统计多个虚函数共用一个private:chara;//占4个字节对齐的问题 int占4字节注意这点和struct的对齐原则很像!! char占一字节补齐3字节char*p;//占4个字节4字节指针intb;//占4个字节staticintd;//非实例独占};classC:publicB{public:C(){}~C(){}virtualvoidtest(){}private://子类的大小是本身成员变量的大小加上父类的大小。intc1;//其中有一部分是虚拟函数表的原因一定要知道父类子类共享一个虚函数指针};classAA1{};classBB1{virtualvoidfun();};classD:publicAA1,publicBB1{};//为了提高实例在内存中的存取效率类的大小往往被调整到系统的整数倍//并采取就近的法则里哪个最近的倍数就是该类的大小intmain(){std::coutclass A: sizeof(A)std::endl;std::coutclass B: sizeof(B)std::endl;std::coutclass C: sizeof(C)std::endl;std::coutclass D: sizeof(D)std::endl;return0;}总结:空的类是会占用内存空间的而且大小是1原因是C要求每个实例在内存中都有独一无二的地址。一类内部的成员变量1、普通的变量是要占用内存的但是要注意对齐原则这点和struct类型很相似。2、static修饰的静态变量不占用内容原因是编译器将其放在全局变量区。二类内部的成员函数1、普通函数不占用内存。2、虚函数要占用4个字节用来指定虚函数的虚拟函数表的入口地址。所以一个类的虚函数所占用的地址是不变的和虚函数的个数是没有关系综合尝试//#pragma pack(2)classBU{//一个Class对象占用内存空间为非静态成员变量总和数据对齐处理虚函数intnumber;unionUBffer{charbuffer[13];//union的大小取决于它所有的成员中占用空间最大的一个成员的大小并且需要内存对齐intnumber;//这里注释#pragma pack(2)那么union大小为16因为与sizeof(int)4对齐如果放开#pragma pack(2)union的大小为14}ubuf;//一个Class对象占用内存空间为非静态成员变量总和 数据对齐处理虚函数。voidfoo(){}//非静态成员函数不占对象内存空间typedefchar*(*f)(void*);//f只是一个定义不是实际上的指针没有占字节。enum{hdd,ssd,blueray}disk;//int4union16enum4内存中当成int来存储4164下面指针int*a;// 指针分平台};算一下放开#pragma pack(2)是多少。关于#pragma pack可参考pragma pack