为什么为结构中的多个数据成员添加填充而不是单个成员?

为什么填充的概念只有在有一个结构体的多个成员时才被添加,为什么只有一个基本的数据types成员时才会被包含呢?

如果我们考虑一个32位机器

struct { char a; } Y; 

没有填充和Y的大小来到1个字节。

如果我们考虑这个结构

 struct { char a; int b; } X; 

X的大小将是8字节。

我的问题是为什么在第二种情况下添加填充? 如果是通过正常读取4bytes数据块的数据的机器进行高效访问,那么为什么在第一种情况下没有填充?

Solutions Collecting From Web of "为什么为结构中的多个数据成员添加填充而不是单个成员?"

在第二种情况下添加了填充,因为在您的机器上, int被对齐到4个字节。 所以它必须居住在一个可以被4整除的地址。

 0x04 0x05 0x06 0x07 0x08 0x09 0x0A 0x0B abbbb 

如果没有填充,则int成员从地址0x05开始,这是错误的。 添加3个填充字节:

 0x04 0x05 0x06 0x07 0x08 0x09 0x0A 0x0B a | padding | bbbb 

现在int0x08 ,这是OK的。

这不仅仅是效率。

这个问题不是访问本身的大小,但它是一致的。 在大多数机器上,访问未对齐的数据将导致程序崩溃,并且在当今的典型机器上, int将需要在四字节边界上对齐的地址:访问其地址未在四字节边界上对齐的int将减慢程序相当大,或导致它崩溃。 您的第一个结构不包含任何数据与对齐方面的考虑,所以没有填充是必要的。 你的第二个有一个int ,并且编译器必须确保给定它们的数组,所有的int都将被正确地对齐。 这意味着1)结构体的总大小必须是4的倍数,2)结构体中int的偏移量必须是4的倍数。 (考虑到第一个要求:

 struct S { char a; int b; char c; }; 

通常会有12的大小,填充两个char后)。

在其他语言中,编译器经常对结构进行重新排序,以便具有最严格的对齐要求的元素首先出现在结构S中,这会导致:

 struct S { int b; char a; char c; }; 

和大小为8,而不是12.但是,C和C ++都禁止这样做。

填充是为了对齐某些数据类型,即确保某个类型的数据的地址是某个指定数字的倍数。 这在不同型号的CPU之间会有所不同,但是通常2字节整数对应的地址是2和4字节整数的地址,而地址是4的倍数。字符通常不需要对齐。

因此,如果一个结构中只有一个字段,那么只要结构放置在具有合适边界的地址处,就不需要填充。 它始终是:系统总是将块对齐到所需的最大边界,通常是4个字节或8个字节。 结构中的一件事将处于适当的边界。 只有在有多个字段时才会出现问题,因为一个字段的长度可能不会导致下一个字段位于正确的边界。 因此,在你的例子中,你有一个字符,这当然需要1个字节,而一个int,它需要4个。假设结构放置在地址0x1000。 然后在没有填充的情况下,字符将被放置在0x1000,而int被放置在0x1001。 但是在4字节边界处int更有效,因此编译器会添加一些填充字节,将其推送到下一个边界0x1004。 所以现在你有char(1字节),填充(3字节),int(4字节),总共8字节。

在这种情况下,没有什么可以改善的。 每个结构将对齐到一个4字节或8字节的边界,所以当最小值为5个字节时,实际上总是至少达到8。 (sizeof将不显示结构之间的填充,只在内部,但内存仍然丢失。)

在其他情况下,您可以通过重新排列字段的顺序来最小化额外填充字节的数量。 就像说你有三个char和三个int。 如果你声明结构为

 struct {char a; int b; char c; int d; char e; int f;} 

那么编译器将在第一个char之后添加3个字节,以便对齐第一个int,然后在第二个char之后再添加三个字节以对齐第二个int。 char(1)+ pad(3)+ int(4)+ char(1)+ pad(3)+ int(4)+ char(1)+ pad(3)+ int(4)= 24。

但是,如果你声明:

 struct {char a; char c; char e; int b; int d; int f;} 

那么你会得到char(1)+ char(1)+ char(1)+ pad(1)+ int(4)+ int(4)+ int(4)= 16。

多年前,我读到的建议,总是把最大的元素,以尽量减少填充,即先把多头,然后整数,然后短裤,然后字符。

如果您正在分配数千或数百万个,则可以通过这种技术节省大量内存。 如果你只是要分配一两个,这不会有太大影响。

Paddingalignment的概念,对于issue of computer efficiency and the speed of the access of the dataissue of computer efficiency and the speed of the access of the data ,对齐的数据可以fetching cycle of the processor from the addresses where the data are storedfetching cycle of the processor from the addresses where the data are stored完美地访问, it doesn't mean that with out alignment processor doesn't work it only meant for the speed access of the memory ,对于整型数据类型来说,它是由编译器完成的4字节对齐,以便处理器更有效地访问数据(在32位系统中)

在字符的情况下只有一个字节只需要的数据,所以不需要对齐,因为每个字节本身是可用的( in RAM there are pages and each page size is 1 byte ),但整数我们需要4字节,没有4字节是有用的能够或者没有什么东西每次访问4个字节,所以编译器制定一个对齐规则,通过这个对齐规则,整数数据在正确的地址中。

并通过它将更快的内存访问数据。