欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

数据对齐存储

程序员文章站 2022-05-22 13:06:38
...

目录

 

计算机里面内存的数据存储结构以及为什么要边界对齐

行边界存储

结构的存储分配规则:

数据的大小端问题

参考文献



计算机里面内存的数据存储结构以及为什么要边界对齐

计算机里面的从主存的是有一个个基本的存储单元构成了,每个存储单元存储的二进制数叫做存储字长

目前一般的存储字长都是64位。同时计算机的主存都是按照字节编址,同时一般来说计算机的CPU只能访问偶数的地址

这种问题,造成了计算机的存储边间的问题。

数据对齐存储

如图所示,如果数据的存储都是紧紧密密的,节约存储空间,那么有可能有些地址无法再某些CPU无法访问,或者是访问需要多次然后进行拼接而成。或者是跨越两个存储单元就进行拼接而成一个数据。

本来CPU就比主存要快很多,如果由于数据的读取问题更让CPU浪费更多的时间,显然是不合理的。


行边界存储

那么为了减少访问次数和平衡空间问题。就要进行边界存储

数据对齐存储

如图所示,空白的部分的地址是空的,没有利用上。确保每个数据的地址都是偶数的,同时尽量跨越少的存储单元。

结构的存储分配规则:

1,编译器按成员列表的顺序为每个成员分配内存
2,结构的起始存储位置为该结构中边界对齐要求最严格的数据类型所要求的位置
3,第一个成员存放在偏移量为0的位置;接下来的各成员存放在偏移量为该成员的类型所占字节数的整数倍的位置;特别地,当成员为结构时,该结构成员存放在偏移量为该结构成员内占空间最大的成员所占字节数的整数倍的位置
4,结构大小为该结构中占用空间最大的成员的所占字节数的整数倍

基于以上规则,我们使用下述做法来减少因边界对齐带来的空间损失:结构中,让对边界对齐要求严格的成员先出现,对边界对齐要求弱的成员后出现

#pragma pack (n):指定对齐值为n(对齐值最多为n)
#pragma pack ():取消自定义对齐值

GCC编译器的默认对齐值:4字节

sizeof操作符可以得到结构的大小
使用stddef.h中定义的offsetof宏来获得结构中某成员的偏移量
offsetof(type, member) 结果为一个 size_t值

eg:

某计算机存储器按字节编址,采用小端方式存放数据,假定编译器规定int和short型长度分别为32位和16位,并且数据按边界对齐存储,其C语言程序段如下:

struct{
    int a;
    char b;
    short c;
}record;
record.a=273;

那么地址和数据的存储如图:

数据对齐存储

如果数据结构修改一下:

struct{
    char a;
    int b;
    short c;
}record;
record.a=273;

那么数据和地址的结构如图:

数据对齐存储

所以要先把对齐要求严格的先安排,也就是字节数短小的先安排了。


数据的大小端问题

数据存储的时候,有个大小端的问题,也就是一个多字节的数据比如所int 的我是先放高8位的数据,还是先放置最低8位的数据

数据对齐存储

如图所示,int Number=0x0123

大端存储的方式:第一个地址存放最高位0x0 ,然后随着地址的值的增加依次存放int Number的后面的数据 

小端存储的方式:第一个数据存储int Number=0x0123的最小位,也就是3 然后随着地址增加依次存放int Number 的高位数


参考文献

 https://blog.csdn.net/yyy_hr/article/details/94338529?utm_source=distribute.pc_relevant.none-task

https://blog.csdn.net/runner_of_nku/article/details/82883245

相关标签: 杂文