如何使用kmalloc执行数据结构对齐?

时间:2011-03-15 10:53:39

标签: c linux data-structures linux-kernel alignment

我一直在阅读数据结构对齐文章,但我无处可去。也许事情太复杂了我无法理解。我还遇到了数据结构填充,这也是对齐数据所必需的。如何在struct usb_ep中添加数据结构填充?另外,我如何确保每次执行kmalloc时,要读取的数据应该是内存偏移量,这是4的倍数?

2 个答案:

答案 0 :(得分:3)

关于对齐,kmalloc将正确对齐结构。如果你有一个4byte变量,它将是4bytes对齐,如果你有一个8byte vaiable,它将是8bytes对齐。理解对齐是需要填充的原因。

您不希望得到的是结构中变量之间的填充填充。您可以使用pragma pack directive(可能最简单)或手动添加填充来执行此操作。

实施例

struct usb_ep
{
 short a;  /* 2 bytes*/
 int b;    /* 4 bytes*/
 short c;  /* 2 bytes*/
};

所有元素的大小为8字节,但由于对齐要求,大小将为12字节。内存布局如下:

short a        - 2 bytes
char pad[2]    - 2 bytes of padding
int b          - 4 bytes
short c        - 2 bytes
char pad[2]    - 2 bytes of padding

为了不获取任何填充或增加结构的大小,您可以重新排列元素以满足对齐要求。

这是一个结构:

struct usb_ep
{
 short a;  /* 2 bytes*/
 short c;  /* 2 bytes*/
 int b;    /* 4 bytes*/
};

大小为8bytes,不需要添加填充。

答案 1 :(得分:1)

这来自http://minirighi.sourceforge.net/html/kmalloc_8c.html

void *  kmemalign (size_t alignment, size_t size)
    Allocate some memory aligned to a boundary.
Parameters:
alignment    The boundary.
size     The size you want to allocate.
Exceptions:
NULL     Out-of-memory.
Returns:
A pointer to a memory area aligned to the boundary. The pointer is a aligned_mem_block_t pointer, so if you want to access to the data area of this pointer you must specify the p->start filed.
Note:
Use kfree(void *ptr) to free the allocated block.

填充结构中字段的最佳方法是以递减的大小声明变量。所以你最大的那个,然后是最小的。

struct example {
  double amount;
  char *name;
  int cnt;
  char is_valid;
};

这并不总是以结构中的逻辑连接项结束,但通常会提供最紧凑且易于访问的内存使用。

您可以在struct声明中使用use padding bytes,但它们会使代码混乱,并且不保证紧凑的结构。编译器可以对齐4字节边界上的每个字节,因此最终可能会使用

struct example2 {
  char a;
  char padding1[3];
  char b;
  char padding2[3];
}; 

a为4个字节,padding1为4个字节,b为4个字节,padding2为4个字节。有些编译器允许您指定在这种情况下会产生正确结果的压缩结构。通常我只是声明从最大到最小类型的字段,并保留它。如果你需要在两个语言/编译器之间共享内存,那么你需要确保结构在内存中对齐相同。