1.根本类型

sizeof运算符返回类型或者数据对象的长度(字节),

  int a=1;   float b=1.0;   double c=1.0;   long d=1;   char e = '1';     cout<<sizeof(a)<<" "<<sizeof(b)<<" "<<sizeof(c)<<" "<<sizeof(d)<<" "<<sizeof(e)<<endl;    cout<<sizeof(int)<<" "<<sizeof(float)<<" "<<sizeof(double)<<" "<<sizeof(long)<<" "<<sizeof(char)<<endl;

输入:

4 4 8 8 14 4 8 8 1

2.动态数组

将sizeof运算符用于动态数组名,失去的是整个数组的字节数,用于数组元素,则失去的是元素长度。

int arr[3]={1,1,1}; float arr1[3]={1.0,1.0,1.0}; double arr2[3]={1.0,1.0,1.0}; cout<<sizeof(arr)<<" "<<sizeof(arr1)<<" "<<sizeof(arr2)<<endl; cout<<sizeof(arr[0])<<" "<<sizeof(arr1[1])<<" "<<sizeof(arr2[2])<<endl;

输入:

12 12 244 4 8

3.动静数组

然而当sizeof运算符用于动静数组,就很神奇。

 vector<int>arr1(1,0);  vector<int>arr2(2,0);  vector<int>arr3(3,0);   cout<<sizeof(arr1)<<" "<<sizeof(arr2)<<" "<<sizeof(arr3)<<endl;

输入:

 24 24 24

能够看到不论vector有多少元素,输出都是24,为啥?

这是因为 vector 是C++规范库中的容器类,其外部实现了三个指针,

  • start;
  • finish;
  • end_of_storage;

别离代表头, 尾(理论应用), vector 存储尾部(占用的,通常大于理论应用),finish-start对应于size(),end_of_storage-start对应于capacity(),如下图所示:

vector 通过配置比其所包容的元素所需更多的内存,即先预留足够空间,防止二次调配,从而进步 vector 的性能。

so,sizeof(vec)其实失去的是三个指针占用内存。在64bit零碎中,一个指针占用8个字节。

4.构造体

构造体成员是依照定义时的程序顺次存储在间断的内存空间,然而构造体大小并不是所有成员大小之和。这波及字节对齐的问题。

4.1 偏移量

偏移量指的是构造体成员地址与构造体地址的差值。构造体大小等于最初一个成员的偏移量加上最初一个成员的大小。显然,构造体变量中第一个成员的地址就是构造体变量的首地址。

4.2 字节对齐

字节是计算机内存的根本单位,然而并不是一一字节存取,而是一次性存取4字节(32位零碎),8个字节(64位零碎),这样子也对拜访地址做了限度,它必须是4,8的倍数。

如果数据地址不是4,8倍数会怎么样?

思考64位零碎,若没内存对齐规定,如果你的数据地址在0x0001-0x0008,因为地址不是0x0000结尾,所以只能别离在0x0000-0x0007和0x0008-0x0015去两次数据,而后剔除多余数据,再把后果返回给你,这样子使得IO变慢。因为计算机CPU速度远远快于内存读写速度,所以缩小内存拜访次数是晋升执行速度的要害。

依照对齐规定存取数据,将数据放在0x0000-0x0008,则可一次性取出,缩小拜访次数,晋升性能。

以下援用于C/C++内存对齐详解

每个特定平台上的编译器都有本人的默认“对齐系数”(也叫对齐模数)。gcc中默认#pragma pack(4),能够通过预编译命令#pragma pack(n),n = 1,2,4,8,16来扭转这一系数。

无效对其值:是给定值#pragma pack(n)和构造体中最长数据类型长度中较小的那个。无效对齐值也叫对齐单位。

字节对齐规定如下

1.第一个构造体成员的地址偏移量为0,当前每个成员偏移量都是成员大小或者无效对齐字节数的最小值的整数倍。如有须要编译器会在成员之间加上填充字节。

2.构造体总大小是无效对齐值的整数倍。如有须要编译器会在最末一个成员之后加上填充字节。

举几个例子

#例1struct stru {  int a;  char b;  int c;  }

例1,a偏移量为0,占用地址空间为0-3,而后b偏移量为4(成员的大小<无效对齐字节),占用地址空间为4,c偏移量不为5,而是8,占用地址空间为8-11,占用了12个字节,又是无效对齐值的整数倍。

#例2struct stru {  char a;  int b;int c;  }

例2,a偏移量为0,占用地址空间为0,而后b的偏移量也不能是1,而是4,b占用的地址空间为4-7,c偏移量为8,占用地址空间为8-11,占用了12个字节。

#例3struct stru {  int a;  char b;  char c;  }

例3,a占用4个字节,地址为0,b偏移量为4(成员大小<无效对齐字节),占用地址空间为4,c偏移量为5(成员大小<无效对齐字节),所以共5个字节,然而须要填充3个字节,所以例3构造大小为8。

#例4struct stru {  char a;int b;  char c;  }

例4,a的偏移量为0,占用地址空间为0,然而b的偏移量不能是2了,应该是4,占用地址空间为4-7,而后c偏移为8,共占用了9个字节,然而整个构造体成员大小为12。