数组的内存对齐方式

我无法在Cell处理器上调整DMA传输的内存。 我需要地址的最后4位为0。

我有4个unsigned int数组,其中每个元素必须在内存中对齐 ,以使其(hex)地址以零结尾。

例如

 int main() { size_t i; static unsigned int a[2] __attribute__ ((aligned (16))); static unsigned int b[2] __attribute__ ((aligned (16))); static unsigned int c[2] __attribute__ ((aligned (16))); static unsigned int d[2] __attribute__ ((aligned (16))); for (i = 0; i < 2; ++i) { printf("a[%u] = %p\n", &a[i]); printf("b[%u] = %p\n", &b[i]); printf("c[%u] = %p\n", &c[i]); printf("d[%u] = %p\n", &d[i]); } return 0; } 

输出:

 a[0] = 0x10010b60 b[0] = 0x10010b50 c[0] = 0x10010b40 d[0] = 0x10010b30 a[1] = 0x10010b64 b[1] = 0x10010b54 c[1] = 0x10010b44 d[1] = 0x10010b34 

这里的问题是每个数组的第二个元素似乎不是16位对齐的(它们的地址’以4结尾)。

我需要地址看起来像这样:

 a[0] = 0xXXXXXXX0 b[0] = 0xXXXXXXX0 c[0] = 0xXXXXXXX0 d[0] = 0xXXXXXXX0 a[1] = 0xXXXXXXX0 b[1] = 0xXXXXXXX0 c[1] = 0xXXXXXXX0 d[1] = 0xXXXXXXX0 

alignment属性指定变量结构字段的对齐,而不是单个数组元素。 有关详细信息,请参阅指定变量的属性 。

如果您始终希望将两个整数对齐,则可以定义结构

 struct dma_transfer { unsigned int e0 __attribute__ ((aligned (16))); unsigned int e1 __attribute__ ((aligned (16))); }; 

这将对齐16字节边界上的元素

 int main(int argc, char **argv) { static struct dma_transfer a; static unsigned int b[2]; printf("a.e0 = %p\n", &a.e0); printf("a.e1 = %p\n", &a.e1); printf("b[0] = %p\n", &b[0]); printf("b[1] = %p\n", &b[1]); return 0; } 

给出,例如

 a.e0 = 0x601060 a.e1 = 0x601070 b[0] = 0x601080 b[1] = 0x601084 

但这也意味着你在两个整数值之间有漏洞。 在32位系统上,您将拥有

| int 4字节| 洞12字节|
| int 4字节| 洞12字节|

如果arr是32位元素的数组,并且arr[0]的地址是0xXXXXXXX0 ,那么arr[1]的地址必然是0xXXXXXXX4

出于您的目的,您需要使用16字节元素的数组:

 typedef struct { unsigned int x; unsigned char reserved[16-sizeof(unsigned int)]; } element_t; static element_t a[2] __attribute__ ((aligned (16))); static element_t b[2] __attribute__ ((aligned (16))); static element_t c[2] __attribute__ ((aligned (16))); static element_t d[2] __attribute__ ((aligned (16))); 

或者,您可以完全避免使用数组。

相反,使用纯变量,并告诉编译器将它们与16个字节对齐:

 static unsigned int a0 __attribute__ ((aligned (16))); static unsigned int a1 __attribute__ ((aligned (16))); static unsigned int b0 __attribute__ ((aligned (16))); static unsigned int b1 __attribute__ ((aligned (16))); static unsigned int c0 __attribute__ ((aligned (16))); static unsigned int c1 __attribute__ ((aligned (16))); static unsigned int d0 __attribute__ ((aligned (16))); static unsigned int d1 __attribute__ ((aligned (16))); 

我真的不认为你能做到这一点……你正试图让编译器在“ unsigned int ”里面为了alighment目的注入额外的填充。 但是没有空间可以做到这一点, unsigned int中的所有位都已用于整数本身。

我认为解决方案是将整数包装在一个结构中,从那时起你可以在结构上使用__attribute__(())魔术,然后创建一个数组。