结构体内存对齐

一、内存对齐的原因
1、为了提高程序的性能,数据结构应该尽可能的在自然边界上对齐。原因是为了访问未对齐的内存,处理器需要进行两次访问而访问对齐的内存只需要一次就够了。这样的方式称为“用空间来换取时间”,在对时间复杂度有要求的问题会采用这样的方法。
2、内存对齐可以增加程序的可移植性,因为不是所有的平台都能随意的访问内存。有些平台只能在特定的地址处取内存。
这里写图片描述
栗子:

#include <iostream>
using namespace std;

struct X
{
     char a;
     int b;
     double c;
}S1;

 void main()
{
     cout << sizeof(S1) << endl;
     cout << sizeof(S1.a) << endl;
     cout << sizeof(S1.b) << endl;
     cout << sizeof(S1.c) << endl;
}

运行结果为:
这里写图片描述
这就是结构体内存对齐的一个很典型的栗子
二、结构体内存对齐的概念
对齐原则:数据存放的起始位置是自身大小的整数倍处。
默认对齐数:在vs下内存默认对齐是8,linux是4。可以通过#program pack来修改默认对齐数。
偏移:相对与起始位置的位置。偏移的是数据类型的整数倍处。
对齐数:变量自身的大小和和默认对齐数的最小值。假设默认对齐数是8,int类型的对齐数是4,那么就会取int类型的默认对齐数。

三、结构体内存对齐的规则
1、结构或联合的数据成员,第一个成员放到0偏移的地方,以后每个成员都放到自身对齐数的整数倍偏移处。
2、结构体的大小必须是最大对齐数的整数倍。
举个栗子:

struct X
{
char a;
double b;
int c;
}s2;
这个栗子是将上面那个栗子的double变量和int型的变量互换了一下位置,但是这个sizeof(s2)却是24,这个就是第二原则的具体情况。我们分析的长度是8 + 8 +4 = 20。但是,结果却是24。因为20不是8的整数倍,所以要把它增容到8的整数倍。
这里写图片描述
下个栗子

struct X
{
    int e;
    double a;
    char b;
    int c;
    char d;
}s3;

这里写图片描述
前面介绍的都是单一的结构体,但是如果结构体里面嵌套一个结构体会怎么样呢?那么就看下一个栗子吧。(今天栗子管够,希望大家能吃好)

struct X
{
    char a;
    int b;
    double c;
};

struct Y
{
    char a;
    X b;
};

经过测试,可知道sizeof(X)为16,sizeof(Y)为24.即Y的长度存放的第二个元素b时的初始位置是在double型的长度的8的整数倍处,而非16的整数倍处,即系统为b分配的存储空间是8~23个字节。
如果将Y的两个元素char型的a和X型的调换顺序,则系统为b分配的存储位置是0~15个字符,为a分配的是第16个字符。17不是double的整数倍,所以要是8的倍数。就是24。

总结:
结构体所占的空间与其内部元素的类型有关,也与它们定义的顺序也是有关的。但是,只要遵守结构体对齐的规则,这也是很简单的。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值