
关键字sizeof的作用是返回对象或类型占用的内存字节数. 返回值为size_t.
基本数据类型占用的字节数: (32位系统)
字符1个字节
布尔1字节
短2个字节
int 4个字节
长4个字节
浮动4个字节
双8个字节
影响结果大小的一个重要因素是字节对齐. 首先看一个公式: 有效对齐值= min(自对齐值,设置对齐值).

自对准值是数据类型本身占用的字节数,
示例:
int a; //自身对齐值是4 char c; //自身对齐值是1 double d; //自身对齐值是8 //对于结构体,自身对齐值是其内置数据类型中对齐值最大的值 struct s1{ int q; //4 bool e; //1 char w; //1 };// 最大的是int q,所以自身对齐值是4 struct s2{ int q; //4 bool e; //1 double r; //8 };// 最大的是double r,所以自身对齐值是8
设置对齐方式值为编译器的默认对齐方式,作者使用vs2013,默认对齐方式为4个字节,可以在Project-> Properties ---> Configuration Properties-> C \ C ++ -->代码生成
--->结构成员对齐方式也可以通过宏#pragma pack(n)设置,n是要设置的对齐字节
有效对齐值是对象或类型的自对齐值和设置的对齐值中的较小者,也是实际的真实对齐值.
在对以上示例进行一些更改之后:
#pragma pack(4) //设置对齐值为4 struct s1{ int q; bool e; char w; }; //s1的自身对齐值是4,所以s1的有效对齐值=min(4,4)=4 #pragma pack(2) //设置对齐值为2 struct s2{ int q; bool e; double r; }; //s2的自身对齐值是8,所以s2的有效对齐值=min(8,2)=2
sizeof可以通过知道有效的对齐值轻松地计算出来.
首先,基本数据类型的大小

sizeof(int)= 4
sizeof(double)= 8
......
第二,结构的大小
#pragma pack(4) struct s1{ int a; char b; }; //有效对齐值是4 sizeof(s1)=8 //int a占4字节,储存在0x00--0x03,char b占1字节,储存在0x04,因为有效对齐值是4,所以char b后面的0x05--0x07补齐对齐,一共占用8字节 //把s1稍作改动 struct s1{ char b; int a; }; //有效对齐值是4 sizeof(s1)=8 //答案一样,但是内部储存情况变了。char b占1字节,储存在0x00,int a占4字节,因为有效对齐值是4,0x01---0x03只剩3字节的内存,小于int a所需的字节数,所以新分配一段4字节(有效对齐值)内存,最终int a储存在0x04---0x07 //再看一个例子 struct s2 { char a; short b; double c; char d; }; //有效对齐值是4 sizeof(s2)=16 //char a占1字节,储存在0x00;short b占2字节,由于有效对齐值是4,第一段内存剩余3字节0x01---0x03,大于short b所需,所以short b储存在0x02---0x03(注意:储存首地址必须是成员大小的整数倍,所以0x01空出);double c占8字节,大于有效对齐值,所以分配两段内存0x04---0x0B用于储存double c;char d占1字节,储存在0x0C,按有效对齐值4字节对齐,最后的0x0D---0x0F补齐对齐。一共16字节。
三,sizeof结构体结构包含sizeof
结构的自对准值是其内置类型中最大的.
示例:
#pragma pack(2) class A { public: int a; double s; }; //A的自身对齐值是double s的自身对齐值,为8 //但A的有效对齐值是min(8,2)=2,sizeof(A)=12 class B { public: char c; //自身对齐值1,占1字节 A b; //自身对齐值8,占sizeof(A)=12字节 }; //B的自身对齐值等于A的自身对齐值,为8 //B的有效对齐值=min(8,2)=2,按2字节对齐 sizeof(B)=14 //char c占1字节,储存在0x00,0x01空出;A b占12字节。一共14字节。
四个,sizeof在结构中包含虚拟函数

具有虚函数的结构将具有一个虚表指针sizeof计算结构体大小,占用4个字节.
示例:
#pragma pack(4) Class A { public: int a; virtual int test(); }; sizeof(A)=8 //int a占4字节,虚表指针占4字节,一共8字节。 //注意:如果一个结构体有多个虚函数,也还是只有一个虚表指针,即多个虚函数共用一个虚表指针
对于继承,如果基类具有虚函数,则虚拟表指针也将被继承,即基类和派生类共享一个虚拟表指针.
示例:
#pragma pack(4) class A { public: int a; double s; virtual int test(); }; class B:public A { public: virtual int test_1(); //共用基类虚表指针 virtual int test_2(); //共用基类虚表指针 char c; }; sizeof(B)=20 //int a占4字节+double s占8字节+虚表指针占4字节+char c占1字节+3字节补齐对齐=20字节
五个sizeof计算结构体大小,联合的大小
联合的成员共享内存,整个联合的大小为每个成员的最大大小.
示例:
union u { int a; double b; char c; bool d; }; sizeof(u)=sizeof(b)=8

六,sizeof包含静态结构
静态和全局变量存储在静态存储区域中,并且在计算结构的sizeof时仅计算非静态成员.
示例:
#pragma pack(4) class A { public: int a; double b; static int d; //不管他 }; sizeof(A)=12 //int a占4字节+double b占8字节=12
七,sizeof函数
结果是函数返回类型的大小,因此对于没有返回值的函数,您找不到sizeof.
格式sizeof(函数名称(实际参数表))
示例:
int A() { return 1; } sizeof(A())=sizeof(int)=4 char B(char b) { return b; } sizeof(B('b'))=sizeof(char)=1 void C() { } sizeof(C()) //error,因为没有返回类型
如果您理解有误,希望您能纠正我! !感激不尽!
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-231673-1.html
看来这个狼真的来了
禽兽不如