Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/64.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 数据结构填充和内存分配_C_Memory Alignment - Fatal编程技术网

C 数据结构填充和内存分配

C 数据结构填充和内存分配,c,memory-alignment,C,Memory Alignment,根据,按此顺序包含单字节和四字节整数的结构将需要额外三个字节的填充,因为四字节整数必须对齐四个字节 按照这种顺序,包含一个四字节整数和一个单字节的结构不需要额外的填充字节,因为一个字节是1字节对齐的 第一个结构的尺寸为8,但第二个结构的尺寸为5 在上面第二个结构之后,在内存中分配的另一个四字节整数呢?它是否会在3个字节的间隔后分配,以便它符合4个字节的对齐方式 [评论更新:] 我忘了提到我的例子是在32位系统上 [更新] 我刚刚发现,在结构的开头和结尾添加的包指令只适用于结构的成员,不会传播到其

根据,按此顺序包含单字节和四字节整数的结构将需要额外三个字节的填充,因为四字节整数必须对齐四个字节

按照这种顺序,包含一个四字节整数和一个单字节的结构不需要额外的填充字节,因为一个字节是1字节对齐的

第一个结构的尺寸为8,但第二个结构的尺寸为5

在上面第二个结构之后,在内存中分配的另一个四字节整数呢?它是否会在3个字节的间隔后分配,以便它符合4个字节的对齐方式

[评论更新:]


我忘了提到我的例子是在32位系统上

[更新]


我刚刚发现,在结构的开头和结尾添加的包指令只适用于结构的成员,不会传播到其他结构。这意味着如果你有一个结构的结构,你必须单独打包,而不仅仅是父结构

也许,也许不是。您可能在一个喜欢填充到8字节边界的体系结构上。 可能地千万不要在编译器中对C结构采用相同的、可预测的二进制表示。甚至在同一编译器中的不同选项之间。 大概在示例架构中,可能是。但事实上,如果编译器的库倾向于分配更大的块,那么差距可能会更大。 也许,也许不是。您可能在一个喜欢填充到8字节边界的体系结构上。 可能地千万不要在编译器中对C结构采用相同的、可预测的二进制表示。甚至在同一编译器中的不同选项之间。 大概在示例架构中,可能是。但事实上,如果编译器的库倾向于分配更大的块,那么差距可能会更大。
数据对齐和打包中缺少的一个考虑因素是,数据对齐至少有两个方面

性能:某些类型的对齐(如4字节int)通常在匹配的四字节地址边界上对齐时执行得更快。这通常是编译器的默认设置。有时也可能进行其他性能较低的对齐。特定于编译器的包选项可以使用这种不太理想的速度布局来实现较少的填充

必需:某些类型的对齐是必需的,例如2字节整数可能会导致奇数地址上的总线故障。特定于编译器的包选项不会违反这一点。填料可能会减少填料,但可能会保留一些填料

回答OP的问题:
一切都是可能的。考虑到它的选项和目标硬件,它是特定于编译器的。

数据对齐和打包中缺少的一个考虑因素是数据对齐至少有两个方面

性能:某些类型的对齐(如4字节int)通常在匹配的四字节地址边界上对齐时执行得更快。这通常是编译器的默认设置。有时也可能进行其他性能较低的对齐。特定于编译器的包选项可以使用这种不太理想的速度布局来实现较少的填充

必需:某些类型的对齐是必需的,例如2字节整数可能会导致奇数地址上的总线故障。特定于编译器的包选项不会违反这一点。填料可能会减少填料,但可能会保留一些填料

回答OP的问题:
一切都是可能的。考虑到它的选项和目标硬件,它是特定于编译器的。

为了给您添麻烦,您可以指示大多数编译器尽可能地减少或删除填充。您的意思是指示编译器将结构的成员打包到某个对齐级别,例如,pack2?这正是我所说的:struct实例总是使用机器地址大小的倍数,并且总是从机器地址大小的地址边界开始。除非在第一个结构实例之前使用pragma包。这也意味着结构中的字段将包含填充,因此字段类型将对齐,即int将在4字节地址边界上对齐。我刚刚发现,在结构开头和结尾添加的打包指令仅适用于结构的成员,不会传播到其他结构。这意味着如果你有一个结构的结构,你必须单独打包它们,而不仅仅是父结构。为了给你添麻烦,你可以指示大多数编译器尽可能减少或删除填充。你的意思是指示编译器将结构的成员打包到某个对齐级别,例如,pack2?这正是我所说的:struct实例总是使用机器地址大小的倍数,并且总是从机器地址大小的地址边界开始。除非在第一个结构实例之前使用pragma包。这也意味着结构中的字段将包含填充,因此字段类型是对齐的,即int将与b对齐
在4字节地址边界上对齐我刚刚发现,在结构开头和结尾添加的包指令只适用于结构的成员,不会传播到其他结构。这意味着如果你有一个结构的结构,你必须单独打包它们,而不仅仅是父结构。我忘了提到我的例子是在32位系统上。这仍然很大程度上取决于编译器。全面的答案可能是正确的,但是正确的测试应用程序并打印出sizeof以供这些结构查看。由于我指定了架构,您的答案有点混乱。在32位体系结构上,除非指示以特定的对齐方式打包数据,否则为什么两个编译器的行为会不同?因为它们可以。他们可以将一个字符填充到1024K,如果他们选择不这样做的话。该标准不强制要求结构对齐。编译器可能有利于空间效率;另一种可能倾向于访问速度,并将所有内容与32位边界对齐;另一个可以根据其malloc库的需要进行调整。你可以整天假设,或者你可以在你的环境中测试你的编译器在做什么。我忘了提到我的例子是在一个32位系统上。这仍然很大程度上取决于编译器。全面的答案可能是正确的,但是正确的测试应用程序并打印出sizeof以供这些结构查看。由于我指定了架构,您的答案有点混乱。在32位体系结构上,除非指示以特定的对齐方式打包数据,否则为什么两个编译器的行为会不同?因为它们可以。他们可以将一个字符填充到1024K,如果他们选择不这样做的话。该标准不强制要求结构对齐。编译器可能有利于空间效率;另一种可能倾向于访问速度,并将所有内容与32位边界对齐;另一个可以根据其malloc库的需要进行调整。您可以整天假设,也可以在您的环境中测试编译器的功能。