1.32位机器和64位机器下面各类型sizeof的大小。
1) 32位机器下:
Char类型:
Size of charis: 1
Size of unsigned charis: 1
Size of signed charis: 1
整型:
Size of intis: 4
Size of shortis: 2
Size of longis: 4
Size of long intis: 4
Size of signed intis: 4
Size of unsigned intis: 4
Size of unsigned long intis: 4
Size of long long intis: 8
Size of unsigned long longis: 8
浮点型:
Size of floatis: 4
Size of doubleis: 8
Size of long doubleis: 8
指针:
Size of (void *) is: 4
Size of (char *) is: 4
Size of (int *)is: 4
Size of (long *)is: 4
Size of (long long *) is: 4
Size of (float *)is: 4
Size of (double *)is: 4
2) 64位机器下
Char类型:
Size of charis: 1
Size of unsigned charis: 1
Size of signed charis: 1
整型:
Size of intis: 4
Size of shortis: 2
Size of longis: 8
Size of long intis: 8
Size of signed intis: 4
Size of unsigned intis: 4
Size of unsigned long intis: 8
Size of long long intis: 8
Size of unsigned long longis: 8
浮点型:
Size of floatis: 4
Size of doubleis: 8
Size of long double is: 16
指针:
Size of (void *)is: 8
Size of (char *)is: 8
Size of (int *)is: 8
Size of (long *)is: 8
Size of (long long *) is: 8
Size of (float *)is: 8
Size of (double *)is: 8
注意:32位机器和64位机器的区别:1)long从4字节变为8字节;2)long double从8字节变为16字节;3)指针从4字节变为8字节,这是因为指针是指向元素的地址,地址从4字节变为8字节,指针自然也会跟着变化。
2.字节对齐的概念
字节对齐:计算机存储系统中以Byte为单位存储数据,不同数据类型所占的空间不同。计算机为了快速的读写数据,默认情况下将数据存放在某个地址的起始位置,如整型数据(int)默认存储在地址能被4整除的起始位置,字符型数据(char)可以存放在任何地址位置(被1整除),短整型(short)数据存放在地址能被2整除的起始位置。这就是默认字节对齐的方式。
3.数组的大小计算
1)对数组执行sizeof运算得到整个数组所占空间的大小,等价于对数组中所有的元素各执行一次sizeof运算并将所得结果求和。注意:sizeof运算不会把数组转化成指针来处理。
如:
char ch[10] = “abcdef”;
cout<<sizeof(ch)<<endl;
cout<<sizeof(*ch)<<endl;
程序运行结果为10和1。因为sieof运算时不会把数组转化为指针来处理,因此sizeof(ch)为10。ch*指向的是字符串的首地址的值,也就是a。因此sizeof(*ch)的值为1。
2)对string对象或vector对象执行sizeof运算只返回该类型固定部分的大小,不会计算对象中的元素占用了多少空间。
如:
vector<int> vec(5);
vec.push_back(9);
cout<<sizeof(vec)<<endl;
程序运行结果为20。这是因为vector的底层实现就是数组,声明vec(5)就相当于已经分配了5个int类型的地址。因此sizeof(vec)的的小为5*4=20。
3)对于函数传递的参数为数组的,因为在传递过程中,实际上是以指针的形式来传递的。因此,它的大小为指针的大小4。
如:
void print(char a[])
{
cout<<sizeof(a)<<endl;
}
int _tmain(int argc, _TCHAR* argv[])
{
char ch[10]=”abc”;
print(ch);
}
4.union和struct的大小计算
1)union大小计算:
对于union,对齐的大小是最大的基本元素的对齐大小;对象的大小必须是该基本元素大小的整数倍;同时要满足实际大小不能小于最大成员的大小。
2)union大小计算举例:
如:
Union U1
{
char a[9];
int b;
};
成员a是char类型,对齐大小为1字节,成员b是int类型,对齐大小是4,所以该union的对齐大小是4。大小为大于等于max(9,4)=9并为4的整数倍,所以是12字节。
3)struct大小计算
先算出struct的对齐大小,对齐的大小也是取决于struct成员中字节对齐最大的那个;然后根据每个成员的对齐大小对每个成员算出分配的空间;最后算出struct实际分配的空间,在满足对齐每个成员的基础上,满足是struct对齐大小的整数倍。
4)struct大小计算举例
如:
struct student
{
char name[5];
int num;
short score;
};
name是char型,对齐大小为1字节,num是int型,对齐大小为4字节,score是short型,对齐大小是2字节,所以student的对齐大小是4字节。数据对齐如下图:
|char|char|char|char|
|char|-----|-----|-----|
|----------int----------|
|--short---|-----|-----|
所以sizeof(student)为16。
如果我们把struct中的变量调换一下顺序,就会得到不一样的结果,比如:
struct student
{
Int num;
char name[5];
short score;
};
对齐大小依然为4字节,数据对齐如下图:
|----------int----------|
|char|char|char|char|
|char|-----|--short--|
所以sizeof(student)为12。
5)特殊情况
如果union或者struct为空,则它们的大小都为1。如果union或者struct中有static变量,则在计算大小时忽略掉static变量,因为static变量不属于union或者struct的一部分。例如:
struct str
{
static int a;
};
计算str大小时,a为static变量,忽略掉。则str相当于一个空的struct,因此sizeof(str)为1。
5.类的大小计算
1)空类
对于一个空类,它的大小为1。
2)简单类
如下定义一个类:
class A
{
public:
int a;
char b;
};
对于简单类的大小,与struct一样。所以sizeof(A)为8。同样的,对于static变量也不属于类的一部分,因此计算大小时,要把static变量忽略掉。
3)带虚函数的类
虚函数放在虚表中,类中定义了虚函数,则需要一个指向虚表的指针。例如:
class B
{
public:
int a;
virtual void print() { }
};
则sizeof(B)的大小为8。需要注意的是,当有多个虚函数的时候,仍然只需要一个指向虚表的指针,因此,如果类中有多个虚函数,仍然只占一个指针的大小。
6.#pragma pack()命令
为了节省空间,我们可以在编码时通过#pragma pack()命令指定程序的对齐方式,括号中是对齐的字节数,若该命令括号中的内容为空,则为默认对齐方式。例如:
#pragma pack(2) //设置2字节对齐
struct student
{
char name[5]; //本身1字节对齐,比2字节对齐小,按1字节对齐
intnum; //本身4字节对齐,比2字节对齐大,按2字节对齐
short score; //本身也2字节对齐,仍然按2字节对齐
};
#pragma pack() //取消设置的字节对齐方式
则student的对齐大小变为2字节,数据对齐如下图:
|char|char|
|char|char|
|char|------|
|-----int-----|
|-----int-----|
|---short---|
所以,sizeof(student)变为12。这样改变默认的字节对齐方式可以更充分地利用存储空间,但是这会降低计算机读写数据的速度,是一种以时间换取空间的方式。
7.笔试题举例
1)2014完美世界笔试填空第11题
class A
{
public:
A(){}
virtual ~A(){}
char m_x;
};
A a;
sizeof(a)的值是:8
解析:虚函数放在虚表中,如果定义了虚函数,则需要存放一个指向虚表的指针。在C++中,指针占4个字节,char类型占1个字节,根据字节对齐的原理,需要占据8个字节,因此类的大小为8。
2)2015腾讯笔试题选择第11题
32位机器上定义如下结构体:
struct xx {
long long _x1;
char _x2;
int _x3;
char _x4[2];
static int _x5;
};
int xx::_x5;
请问sizeof(xx)的大小是()D
A.19 B.20 C.15 D. 24
解析:_x5位static变量,不占struct的内存空间。_x1对齐大小8个字节,_x2和_x4对齐大小为1个字节,_x3对齐大小为4个字节,所以xx的对齐大小为8字节。字节对齐图如下:
|----------long long----------|
|char|--------|-------int-------|
char|char|--------------------|
所以xx总共会占24个字符。