第四课:结构体成员字节对齐及字节数计算

功能描述:结构体字节对齐及字节数计算

一、结构体占用字节数计算

结构体存储变量时地址要求对齐!!!

以 struct ABCD 为例:

struct ABCD
{
    char A;
    short B;
    int C;
    double D;
};

(1) 找出结构体中所有成员占用字节数最多的那个成员类型,它占用的字节数即为对齐的字节数,结构体 ABCD 中成员 D 的类型位 double,占用 8 个字节,则这个结构体为 8 字节对齐。

(2) 按上述字节对齐,从上往下依次存储成员变量,如果存储的成员字节总数大于对齐字节数,则上一对齐字节剩余部分补 0,该成员存到下一个对齐字节的内存中上述中 A、B、C 加一起 7 字节,则一个 8 字节内存够用,那么 sizeof(ABCD) 则为 16,此处 A、B、C 占用一个 8 字节,D 占用一个 8 字节。

struct ABCD
{
    int A;
    short B;
    int C;
    double D;
};

如果是 int A,则 sizeof(ABCD) 则为 24。此时,对齐方式为 8 字节对齐,A 为 int 型 4 字节,B 为short 型 2 字节,C 为 int 型 4 字节,D 为 double 型 8 字节,A+B+C 为 10 字节,大于对齐 8 字节,A+B 为 6 字节,小于对齐 8 字节,因此, A、B 占用一个 8 字节,C 占用一个 8 字节,D 占用一个 8 字节,共计 24 字节。

二、强制设置结构体字节对齐方式

有时我们为了简化成员变量的存取,特别是在 UDP 或者 TCP 通信时,收发数据不一致时,可能就是字节对齐方式导致的。因此,我们可以采用 #pragma pack(push) 、#pragma pack(1)  #pragma pack(pop) 的方式设置字节对齐方式,一般设置为单字节对齐

#pragma pack(push)                // 保存默认字节对齐方式
#pragma pack(1)                   // 设置单字节对齐

struct ABCD
{
    char A;
    short B;
    int C;
    double D;
};

#pragma pack(pop)                // 恢复默认字节对齐方式

ABCD 对齐方式为单字节对齐,A 占用 1 字节, B 占用 2 字节,C 占用 4 字节,D 占用 8 字节,因此 sizeof(ABCD) 为 15。

三、测试验证

在 Qt 中测试验证代码如下:

#include 
#include 

#pragma pack(push)
#pragma pack(1)

struct ABCD
{
    char A;
    short B;
    int C;
    double D;
};

//struct ABCD
//{
//    int A;
//    short B;
//    int C;
//    double D;
//};


#pragma pack(pop)

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    qDebug() << sizeof(ABCD);

    return 0;
}

你可能感兴趣的:(Qt,实战经验,算法,数据结构,Qt)