最近公司的软件需要从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了,嘿嘿)