我刚刚学到了关于如何优化记忆的新知识。
概念上说:变量总是存储在一个8字节的区域中,如果不是8字节,它将被填充。
你可以看到这张照片的插图。

我试着用sizeof()命令测试它,讽刺的是它没有像预期的那样工作。对吗?我怎么用代码来证明呢?
发布于 2022-04-02 17:12:17
我认为你误解或曲解了你所受的教育。声明:
变量将始终存储在8字节的区域中,
图不支持(事实上是显式矛盾的),如果这是真的,那么任何数量的“变量排列”都不会对内存使用产生任何影响,因为所有成员都会占用相同的填充空间。这根本不是图表所说明的,我也怀疑你并没有真正学到什么。
它在任何情况下都是定义的实现,例如8、16、32和64位平台可能具有不同的最佳对齐方式,如果优化目标是最小空间,或者应用编译器指令或选项来强制不同的对齐,编译器可以也可能不会产生最佳性能对齐。
例如,您的图表表明,如果交换了bool和double,那么结构大小可能是16字节,而不是24字节。
关于:
如何用代码来证明它?
因为它是定义的,所以您可以在某些平台/编译器实现中同样地否定它。然而,为了检验这一假设,并调查任何具体的执行情况,请考虑:
#include <stdio.h>
#include <stdbool.h>
#include <stdint.h>
int main()
{
struct
{
bool a ;
double b ;
uint16_t c ;
uint32_t d ;
} foo ;
struct
{
double b ;
bool a ;
uint16_t c ;
uint32_t d ;
} bar ;
printf("foo: %lu\n", sizeof(foo) ) ;
printf("bar: %lu\n", sizeof(bar) ) ;
return 0;
}至少在https://onlinegdb.com/jknxFt0Sx中,它输出:
foo: 24
bar: 16它演示了图表中所建议的行为,但显然否定了“变量将始终存储在8字节的区域,.”。
更重要的是,在应用了实现、定义的对齐和填充之后,通常依赖于成员各自大小的成员排序会影响结构的总体大小。
图表实际上说明的是,成员对齐取决于它们的大小。因此,单个字节可以有任意地址,16位类型甚至有地址,32位类型具有可被4除的地址,64位类型可以被8除。现在,在任何特定的实现中,这可能是正确的,也可能不是正确的,但是最小化结构的大小的方法是分组成员,使它们在保持所需的对齐的同时没有填充。
通常,默认对齐可以被操作(由编译器定义的机制)。比如gcc:
struct
{
bool a ;
double b ;
uint16_t c ;
uint32_t d ;
} __attribute__((packed)) foo ;
struct
{
double b ;
bool a ;
uint16_t c ;
uint32_t d ;
} __attribute__((packed)) bar ; 结果在这两种结构的大小为15,而不管平台的首选或所需的对准。在不支持对齐访问的平台上,这种结构会生成额外的代码来访问未对齐的成员,并且在某些(Mis)中可能会导致异常。
发布于 2022-04-02 17:39:30
你把尺寸和对齐搞混了
字符的大小总是1,它由c标准定义。
对齐是指该变量的地址是某个特定值(通常为2、4、8或16)的倍数。
为什么变量是对齐的?在一些CPU上,各种类型的数据必须以均匀的边界或4的倍数开始。其他CPU类型的数据对齐性好得多。编译器知道这一点,因此他们将在内存中布局东西,以便正确地和/或优化地对齐。
看见
Why is integer assignment on a naturally aligned variable atomic on x86?
INTEL X86,why do align access and non-align access have same performance?
对齐导致变量之间未使用内存。
THe sizeof运算符告诉您变量的大小,而不管它是如何对齐的。它没有考虑到调整。
https://stackoverflow.com/questions/71719159
复制相似问题