结构体嵌套对齐

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了结构体嵌套对齐相关的知识,希望对你有一定的参考价值。

64 位的优点:64 位的应用程序可以直接访问 4EB 的内存和文件大小最大达到4 EB(2 的 63 次幂);可以访问大型数据库。本文介绍的是64位下C语言开发程序注意事项。


1. 32 位和 64 位C数据类型

32和64位C语言内置数据类型,如下表所示:

技术分享

上表中第一行的大写字母和数字含义如下所示:
I表示:int类型
L表示:long类型
P表示:pointer指针类型
32表示:32位系统
64表示64位系统

如:LP64表示,在64位系统下的long类型和pointer类型长度为64位。
64位Linux 使用了 LP64 标准,即:long类型和pointer类型长度为64位,其他类型的长度和32位系统下相同类型的长度相同,32位和64位下类型的长度比较见上图的蓝色部分。
下图为在32和64位linux系统下使用sizeof检测出的数据类型的长度。
32位平台下结果:

技术分享

64位平台下结果:

技术分享



主流都是64位了。所以都按照64位的来。


sizeof对齐问题。

1,如果class或struct里面有基本类型数组,则数组应该按照结构体对齐值的倍数对齐。

而结构体对齐值应该是基本变量的最大值,这里是int, 即4.
///4+4
struct SZ
{
    char c[2];
    int a;
};


///2+2+4=8
struct SZ2
{
    char c[2];
    short b;
    int a;
};

///4+4+4=12
struct SZ3
{
    char c[2];
    int a;
    short b;
};

///4+4+4=12
struct SZ4
{
    char c[6];
    int a;
};

结果:

sizeof of   SZ:8

sizeof of   SZ2:8

sizeof of   SZ3:12

sizeof of   SZ4:12



又这里基本类型最大是long,按8对齐。

///align8   8*2+8=24
struct SZ
{
    long c[2];
    int a;
};


///align8  8*2+8=24
struct SZ2
{
    long c[2];
    short b;
    int a;
};

///align8  8+2*8+8+8=40
struct SZ3
{
    char c[2];
    long a[2];
    int b;
    int i;
    short s;
};

///align8 48+8=56
struct SZ4
{
    long c[6];
    int a;
};


sizeof of   long:8

sizeof of   SZ:24

sizeof of   SZ2:24

sizeof of   SZ3:40

sizeof of   SZ4:56


2,如果class或struct里面有其他自定义类型。 如果基本类型跟的是其他类型,则直接拼接,即使超过对齐数

对齐值是基本类型的最大值。

struct THREE
{
    char a[3];
};
///align1 3+1=4
struct SZ
{
    THREE t;
    char a;
};
///align8   8*2+8=24
struct SZ2
{
    long c[2];
    THREE b;
    int a;
};
///align4   1+3  +4  +4 =12
struct SZ3
{
    char c;
   THREE t;
   int i;
    short s;
};
///如果基本类型下一个是其他类型,则直接拼接不用对齐。
/// align4  not 4+4+4+4=16 //err
///align4   should be:   2+2  +1+2+1(null)  +4 =12
struct SZ4
{
    char c[2];
   THREE t;
    short s;
    int a;
};
///align4  2+2  +1+1+2(null) +4=12
struct SZ5
{
    char c[2];
   THREE t;
    char s;
    int a;
};
///align4  2+2  +1+3(null)  +4*2 =16
struct SZ6
{
    char c[2];
   THREE t;
    int s;
    int a;
};
//sizeof of   THREE:3
//sizeof of   SZ:4
//sizeof of   SZ2:24
//sizeof of   SZ3:12
//sizeof of   SZ4:12
//sizeof of   SZ5:12
//sizeof of   SZ6:16



3,如果结构体里面有其他类型的数组,则:

最大对齐值是最大的基本类型

如果后面跟的是其他类型数组,直接拼接,即使超了。   如果后面跟的是基本类型,未超可以拼接。超了要补空对齐。

struct THREE
{
    char a[3];
};
///align1 6+1=7
struct SZ
{
    THREE t[2];
    char a;
};
///align8   8*2+8+8=32
struct SZ2
{
    long c[2];
    THREE b[2];
    int a;
};
///align4    1+6+1(null)+4+4=16
struct SZ3
{
    char c;
   THREE t[2];
   int i;
    short s;
};
///如果基本类型下一个是其他类型,则直接拼接。
///align4   should be:   2+6  +4  +4 =16
struct SZ4
{
    char c[2];
   THREE t[2];
    short s;
    int a;
};
///align8   8+ 3+6+1+4+2(null) =24
struct SZ5
{
    long l;
    char c[3];
   THREE t[2];
    char s;
    int a;
};
///align8   8+6+2(null) +4+4(null) =24
struct SZ6
{
   long l;
   THREE t[2];
    int s;
};
//sizeof of   THREE:3
//sizeof of   SZ:7
//sizeof of   SZ2:32
//sizeof of   SZ3:16
//sizeof of   SZ4:16
//sizeof of   SZ5:24
//sizeof of   SZ6:24


以上是关于结构体嵌套对齐的主要内容,如果未能解决你的问题,请参考以下文章

结构体嵌套对齐

Visual Studio2008 C++结构体成员需要内存对齐吗?

结构体变量的sizeof计算

内存字节对齐

内存字节对齐

C语言 如何计算结构体的大小