字节不对齐,后果很严重

来源:互联网 发布:php qrcode csdn 编辑:程序博客网 时间:2024/05/16 18:46

最近公司的软件需要从windows版本移植到solaris版本(我们用的V240机器,sparc芯片,solaris9),移植倒是很顺利,虽然vc对C++标准的支持不是很严格,到了GCC以后,很多地方编译不过,但毕竟只是语法的问题,调整一下就编译过去了,但是程序运行的时候,发现有的用例跑起来的时候会导致程序core dump。使用GDB调试了好几次,都是在某个对int指针赋值的时候,程序崩溃了,这就让人纳闷了,这么简单的赋值还能让程序崩溃了? 后来鬼使神差的看了一下指针地址,发现地址内存地址是个奇数。开始怀疑是不是内存地址没有对齐的问题,于是写了一个demo测试了一把:

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

在solairs下编译后运行,果然在*pi = 1那行抛出了一个bus error,直接core dump了。

最后上网查询资料,得出结论:

sparc芯片,必须要求字节对齐,如果不对齐,就会core dump。

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

再查资料:

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

推广:

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

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

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

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

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

(终于鼓起勇气,第一次写blog了,嘿嘿)