空类,没有任何成员变量或函数,即没有存储任何内容;但是空类仍然可以实例化,如:classA A; cout<<"sizeof(A): "<<sizeof(A)<<endl;输出为1,。一个类能实例化就会分配内存空间,来指示它的地址。默认分配了一个字节(如:char),以标记可能初始化的类实例,同时使空类占用的空间也最少(即1字节)。
内存对齐可以提高CPU访问的速度和效率。
内存的自然对齐:每一种数据类型都必须放在地址中的整数倍上 。举个例子如下:
地址4可以放char(1)类型,可以放int(4)型,可以放short(2)型,但是不能存放double(8)型,仅仅因为4不是8的整数倍。 地址3能存放char型,但是其他int,short,double都不能存放。 有一个特殊地址,就是0,它可以是任何类型的整数倍,所以可以存放任何数据。 根据这个规则,那么在分配一大块包含很多变量的内存的时候,会产生很多碎片。
#include<stdio.h>
#include<stdlib.h>
typedef strutc test{
char a;
int b;
double c;
char d;
}
int main(void)
{
STU s;
printf("s的大小是 = %d\n",(int)sizeof(STU));
printf("s中a的起始地址是 %p\n",&(s.a));
printf("s中b的起始地址是 %p\n",&(s.b));
printf("s中c的起始地址是 %p\n",&(s.c));
printf("s中d的起始地址是 %p\n",&(s.d));
return 0;
}
/*64位下
s的大小是 = 24
s中a的起始地址是 0x7ffd01319d10
s中b的起始地址是 0x7ffd01319d14
s中c的起始地址是 0x7ffd01319d18
s中d的起始地址是 0x7ffd01319d20
*/
依照简单的4字节对齐,首先的char在0上(其实也就是某个4的整数倍数上),之后int b在地址4上,一直延续到8,double c就在地址8上,之后sizeof必须是8的整数倍,之前是4+4+8 == 16,那这个char就只能存入一个8大小的内存中了,也就是4+4+8+8 == 24。
开始的可以根据内存的自然对齐求得,最后的char补7个空白是因为结构体的总大小,必须要是其内部最大成员的整数倍,不足的要补齐,像这里就是double 8个字节的整数倍,所以给最后的d补上了7个空白空间。这也是内存分配的3个原则之一。
关于内存分配的其他两个规则如下:
1.结构体或union联合的数据成员,第一个数据成员是要放在offset == 0的地方,如果遇上子成员,要根据子成员的类型存放在对应的整数倍的地址上
2.如果结构体作为成员,则要找到这个结构体中的最大元素,然后从这个最大成员的整数倍地址开始存储(strutc a中有一个struct b,b里面有char,int,double….那b应该从8的整数倍开始存储)
32位限制了一次只能读入4个字节数据处理,也就是说8字节的double被分成了2个4字节字符被处理,也可以说死了,32位平台下就定死了4字节对齐
typedef struct stu{
char a;
int b;
char ex;
double c;
char d;
}S;
printf("S的大小是 = %d\n",(int)sizeof(S));
/*32位输出
S的大小是 = 24 //a( 4 )+b( 4 )+ex( 4 )+c( 4+4 )+d( 4 ) == 24
*/
/*64位输出
S的大小是 = 32 //a( 4 )+b( 4 )+ex( 8 )+c( 8 )+d( 8 ) == 32
*/
结合之前说的内存的自然对齐,我们知道char遇到int型,产生3个空白,遇上double要产生7个空白。而这里32位中的char遇上double却只是产生了3个空白,是因为32位限制了一次只能读入4个字节数据处理,也就是说8字节的double被分成了2个4字节字符被处理,也可以说死了,32位平台下就定死了4字节对齐.结构体中最大的数就是4字节的了,sizeof(S)也只需要遵守是4的整数倍即可。最后得到24字节。
typedef struct bb
{
int id; //[0]....[3]
double weight; //[8].....[15] 原则1
float height; //[16]..[19],总长要为8的整数倍,补齐[20]...[23] 原则3
}BB;
typedef struct aa
{
char name[2]; //[0],[1]
int id; //[4]...[7] 原则1
double score; //[8]....[15]
short grade; //[16],[17]
BB b; //[24]......[47] 原则2
}AA;
int main()
{
AA a;
cout<<sizeof(a)<<" "<<sizeof(BB)<<endl;
return 0;
}
/*输出
48 24
*/