字节对齐的问题

来源:互联网 发布:mysql 主从备份 主键 编辑:程序博客网 时间:2024/06/11 23:05


字节对齐的细节和具体编译器实现相关,表现为具体的汇编翻译可能会因为编译器的不同而不同,但一般而言,满足三个准则:

1) 结构体变量的首地址能够被其最宽基本类型成员的大小所整除;
2) 结构体每个成员相对于结构体首地址的偏移量都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字节;例如上面第二个结构体变量的地址空间。

3) 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节。

例如:

int main()
{
    char s[100] = {0};
    int* pi = (int*)&s[1];
    *pi = 1;
     return 0;
}

 

在keil(M0内核)下编译后运行,果然在*pi = 1那行抛出了一个总线错误;

必须要求字节对齐,否则就会出错

经过测试,如果你的变量是两字节的,如short类型,那么内存地址必须能够被2整除。如果是四字节变量,那么内存地址必须能够被4整除,一个字节的,如char型,那就无所谓了


一般risc架构都会要求字节必须对齐,否则就会有问题,但是x86的芯片没有问题,当内存地址不对齐时,芯片会自动分两次读取数据,只是影响效率,不会有程序崩溃的危险。

因此,如果是自己定义的类和结构体,尽量显示的让它字节对齐,这样在跨平台的时候就不会有问题,如:

struct XX{
    char a;
    short b;
    int c;
};

这个结构体在四字节对齐的情况下,sizeof(xyz) = 8,如果你定义成:

struct xyz{
    char a;
    char b;
    shortc;
    int d;
};

占用的空间是一样的,但是移植起来就方便了。


1 0
原创粉丝点击