C++ 之sizeof对齐问题

sizeof的对齐问题是C/C++里面一个比较经典的问题,在了解这些问题之前我们首先需要有一些先验知识。

C/C++ 不同数据占用内存大小

数据类型 32位 64位
char 1 1
int 4 大多数时候为4,少数为8和编译器有关
short 2 2
long 4 8
float 4 4
double 8 8

sizeof的用法

sizeof 是一个关键字,它是一个编译时运算符,用于判断变量或数据类型的字节大小。
sizeof 运算符可用于获取类、结构、共用体和其他用户自定义数据类型的大小。
使用 sizeof 的语法如下:

sizeof(type datatype);

对于简单数据类型有sizeof(int)=4,sizeof(double)=8。对于数组而言有

#include<iostream>
using namespace std;

int main()
{
    int a[3];
    cout<<sizeof(a);
    return 0;
}

最后的输出结果为12。所以数组的大小即为数组数 × sizeof(datatype)。

结构体对齐问题

对于结构体而言,存在一个对齐问题,不能简单的将里面成员大小相加。例如:

typedef struct s
{
    int a;
    char c;
    int j;
};

如果和数据一样处理,那么会有sizeof(s)=9,但是实际运行结果如下:
这里写图片描述

为什么会出现这种情况呢?这里我们先要知道编译器在编译时会遵循的两条原则
(1)结构体变量中成员的偏移量必须是成员大小的整数倍(0被认为是任何数的整数倍)
(2)结构体大小必须是所有成员大小的整数倍,也即所有成员大小的公倍数。

首先解释下偏移量,偏移量指的是结构体成员地址与结构体地址之间的差。所以a的偏移量为0,c的偏移量必须为成员的倍数,其实也是最小公倍数,即偏移量为4。而j的地址就变成了4+1=5,此时会补齐3位,这样才满足(1),因此j的偏移量为8。因此结构体的大小为8+4=12。如果对于这个例子还是不理解,可以看看下面两个例子:

typedef struct s1
{
    char a;
    char c;
    int j;
};

typedef struct s2
{
    int a;
    double b;
    char c;
};

所以根据上面两条原则,sizeof(s1)=8,sizeof(s2)=24。
至于结构体里嵌套结构体,其实就是将嵌套结构体当成一个成员来分析,其他都是一样,就不在赘述。

猜你喜欢

转载自blog.csdn.net/gzj_1101/article/details/80265587