当前位置: 技术问答>linux和unix
内存对齐的问题,会的请进
来源: 互联网 发布时间:2016-09-21
本文导语: 在调裸机的USB驱动的时候,发现在端点描述符中的MaxPacketSize这个变量占的是两个字节,在U-BOOT中将它定义为unsigned short型的占两个字符,其中端点描述符总共是7个字节,在MaxPacketSize的前面和后面还有几个是定...
在调裸机的USB驱动的时候,发现在端点描述符中的MaxPacketSize这个变量占的是两个字节,在U-BOOT中将它定义为unsigned short型的占两个字符,其中端点描述符总共是7个字节,在MaxPacketSize的前面和后面还有几个是定义为unsigned char型的变量,现在问题来了。在调试的过程中发现,当MaxPacketSize处于奇地址的时候,使用这个变量的时候程序会死掉。应该是内存对齐的问题,因为我前一个端点打印出来的时候,MaxPacketSize是处于偶地址的。于是我将MaxPacketSize放到了端点描述符结构体的开头,调试后还是不行。于是我将MaxPacketSize改为了两个unsigned char的变量,在使用的时候使用位移就行了。
请问除了这个方法,还有别的解决内存对齐的问题吗?
其中在结构体的定义的时候,在后面加了个__attribute__((packet)),查资料得知是GCC的对齐方式,这里强制以模1对齐,结构体如下:
C/C++ code
struct usb_endpoint_descriptor {
unsigned char bLength;
unsigned char bDescriptorType;
unsigned char bEndpointAddress;
unsigned char bmAttributes;
//unsigned char wMaxPacketSizeL;
//unsigned char wMaxPacketSizeH;
unsigned short wMaxPacketSize;
unsigned char bInterval;
unsigned char bRefresh;
unsigned char bSynchAddress;
//} __attribute__ ((packed));
};
当不加__attribute__ ((packed))得出的结构体大小是10个字节,在使用的时候就不知道出现程序死掉的现象了。当不加__attribute__ ((packed))的时候,得出的大小是9个字节,如果使用的时候就会出现程序死掉的情况。
加入__attribute__ ((packed))这一行是设定编译器取消在编译过程中的内存对齐方式,如果是这样的化,比如像上面的一样,在一串char中间有short,int的变量,而且它们刚好在奇地址上要怎么访问呢?
请问除了这个方法,还有别的解决内存对齐的问题吗?
其中在结构体的定义的时候,在后面加了个__attribute__((packet)),查资料得知是GCC的对齐方式,这里强制以模1对齐,结构体如下:
C/C++ code
struct usb_endpoint_descriptor {
unsigned char bLength;
unsigned char bDescriptorType;
unsigned char bEndpointAddress;
unsigned char bmAttributes;
//unsigned char wMaxPacketSizeL;
//unsigned char wMaxPacketSizeH;
unsigned short wMaxPacketSize;
unsigned char bInterval;
unsigned char bRefresh;
unsigned char bSynchAddress;
//} __attribute__ ((packed));
};
当不加__attribute__ ((packed))得出的结构体大小是10个字节,在使用的时候就不知道出现程序死掉的现象了。当不加__attribute__ ((packed))的时候,得出的大小是9个字节,如果使用的时候就会出现程序死掉的情况。
加入__attribute__ ((packed))这一行是设定编译器取消在编译过程中的内存对齐方式,如果是这样的化,比如像上面的一样,在一串char中间有short,int的变量,而且它们刚好在奇地址上要怎么访问呢?
|
只需要注意大小,长短就可以了。不需要具体的地址吧。
理论上搞不清楚,就用sizeof()来统计核对。
理论上搞不清楚,就用sizeof()来统计核对。
|
两种方法,一种pack,一种手动加pad。
|
内存不对齐,可能导致代码core掉。
搞清为何要内存对齐,就可以解释你的问题了。
http://www.fish888.com/-t149534
http://bigwhite.blogbus.com/logs/1347304.html
1、平台原因(移植原因):不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。
搞清为何要内存对齐,就可以解释你的问题了。
http://www.fish888.com/-t149534
http://bigwhite.blogbus.com/logs/1347304.html
1、平台原因(移植原因):不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。
|
我觉得首先要搞清楚的问题是为什么不对齐程序就会死掉,而不是如何去对齐。
|
觉得从现象上来看也不一定就是内存对齐问题,建议仔细看看逻辑,不要先入为主的好。