由于基础不够扎实,前几天在工作中踩了一个坑,实在忍不了了,写个博客记录一下。
一、字节对齐的概念
内存空间是按照字节划分的,从理论上来讲对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定类型变量的时候经常在特定的内存地址访问。这就需要各种类型的数据按照一定的规章在空间上排列,而不是顺序的一个接一个的排放,这就是对齐。
对齐跟数据在内存中的位置有关,如果一个变量的内存地址正好位于它长度的整数倍,他就被称作自然对齐。如32位cpu下,假设一个整型变量的地址为0x00000004,它就自然对齐的。
二、字节对齐的必要性
各个硬件平台对存储空间的处理有很大不同,如果不按照合适其平台要求对数据存放进行对齐,会在存取效率上带来损失。
例如:假设上面整型变量的地址是0x00000006,则CPU需访问两次内存才能取到值。第一次取0x00000006-0x00000007的一个short,第二次取0x00000008-0x00000009的一个short,然后组合成int。如果变量在0x00000007地址的话,则要访问三次内存,第一次为char,第二次为short,第三次为char,然后组合成int。而如果变量在自然对齐的位置上,则只要一次就可以取出数据。
三、我遇到的字节对齐问题
typedef _req{
unsigned int req_num;
char word;
}req;
req r;
sizeof(r)的值是几?不是5!是8!结构体中每个数据类型都要求对齐!默认是按照4个字节存储,所以char在存储的时候填充3个字节,使整个结构体对齐。
但是在ruby中是采用字节紧缩的方式存储变量,即sizeof(r)的值的5!
这会导致如果用ruby脚本构造请求,和C语言的可执行程序进行网络交互时,请求字段总是因为长度不匹配导致不会被正确解析。而莫名“丢失”的字节在程序打印的日志中又很难追查。曾经被这个小白问题卡住了,记录一下。