结构体对齐
许多实际的计算机系统对基本类型数据在内存中存放的位置有限制,它们会要求这些数据的起始地址的值是某个数k的倍数,这就是所谓的内存对齐,而这个k则被称为该数据类型的对齐模数(alignment modulus)。
这种强制的要求一来简化了处理器与内存之间传输系统的设计,二来可以提升读取数据的速度。
总的来说就是方便寻址,要不然内存中的地址长短不一,寻址的时间复杂度将会增大。
几个具体例子
#include<bits/stdc++.h>
#define ll long long
using namespace std;
struct node
{
char a;
int b;
};
int main()
{
cout<<sizeof(node)<<endl;
return 0;
}
结果是8,char类型是1,int类型是4,但是由于char类型比较小,要在其后面进行填充来保证对齐,因此char实际上也变成了4,所以结果为8.
#include<bits/stdc++.h>
#define ll long long
using namespace std;
struct node
{
char a;
char c;
int b;
};
int main()
{
cout<<sizeof(node)<<endl;
return 0;
}
结果是8
#include<bits/stdc++.h>
#define ll long long
using namespace std;
struct node
{
char a;
int b;
char c;
};
int main()
{
cout<<sizeof(node)<<endl;
return 0;
}
结果是12
两个结构体的内容完全一样,但是由于上面的对齐缘故,在第二段代码中,char a是4,int是4,char c也是4,综合是12.
在第一段代码中,char a,char c都是1,合起来是2,填充2个补足4个,int类型也是4,故一共是8
因此
#include<bits/stdc++.h>
#define ll long long
using namespace std;
struct node
{
char a;char c;char d;char e;
int b;
};
int main()
{
cout<<sizeof(node)<<endl;
return 0;
}
即使是这样,结果也是8,但是如果再来一个char f,结果就会变成12.
具体的计算方法请参考这篇博客:https://www.cnblogs.com/motadou/archive/2009/01/17/1558438.html
空结构体
上面说了对齐的相关内容,那么空结构体的大小是多少呢?0?其实不是,答案是1!
#include<bits/stdc++.h>
#define ll long long
using namespace std;
struct node
{
};
int main()//结果是1
{
cout<<sizeof(node)<<endl;
return 0;
}
这是因为,C++标准中规定,“no object shall have the same address in memory as any other variable” ,就是任何不同的对象不能拥有相同的内存地址。 如果空类大小为0,若我们声明一个这个类的对象数组,那么数组中的每个对象都拥有了相同的地址,这显然是违背标准的。