C结构大小对齐

时间:2012-06-21 00:40:20

标签: c struct alignment

我希望C结构的大小是16字节的倍数(16B / 32B / 48B / ..)。 它到达的大小无关紧要,它只需要是16B的倍数。 我怎么能强制编译器这样做? 感谢。

4 个答案:

答案 0 :(得分:12)

对于Microsoft Visual C ++:

#pragma pack(push, 16)

struct _some_struct
{
     ...
}

#pragma pack(pop)

GCC:

struct _some_struct { ... } __attribute__ ((aligned (16)));

示例:

#include <stdio.h>

struct test_t {
    int x;
    int y;
} __attribute__((aligned(16)));

int main()
{
    printf("%lu\n", sizeof(struct test_t));
    return 0;
}
使用gcc -o main main.c编译的

将输出16。其他编译器也是如此。

答案 1 :(得分:6)

C结构的大小取决于结构的成员,它们的类型以及它们的数量。实际上没有标准方法可以强制编译器使结构变为某个大小的倍数。有些编译器提供了一个pragma,它允许你设置对齐边界,但这实际上是另一回事。并且可能会有一些会有这样的设置或提供这样的实用工具。

但是如果你坚持这个方法,那就是对结构进行内存分配,并强制内存分配向下舍入到下一个16字节大小。

所以如果你有这样的结构。

struct _simpleStruct {
   int iValueA;
   int iValueB;
};

然后你可以做以下的事情。

{
    struct _simpleStruct *pStruct = 0;
    pStruct = malloc ((sizeof(*pStruct)/16 + 1)*16);
    // use the pStruct for whatever
    free(pStruct);
}

这样做的目的是将大小推到下一个16字节大小,就你所担心的而言。但是,内存分配器可能会或可能不会为您提供实际大小的块。内存块实际上可能比您的请求更大。

如果您要对此做一些特别的事情,例如假设您要将此结构写入文件,并且您想知道块大小,那么您必须执行malloc中使用的相同计算()而不是使用sizeof()运算符来计算结构的大小。

接下来就是使用宏来编写自己的sizeof()运算符,如。

#define SIZEOF16(x) ((sizeof(x)/16 + 1) * 16)

据我所知,没有可靠的方法从指针中提取已分配块的大小。通常,指针将具有内存堆管理功能使用的内存分配块,该内存堆管理功能将包含各种内存管理信息,例如分配的块大小,实际上可能大于请求的内存量。但是,此块的格式以及它相对于提供的实际内存地址的位置取决于C编译器的运行时间。

答案 2 :(得分:5)

这完全取决于编译器和其他工具,因为未在ISO C标准中明确指定对齐(它指定对齐可能发生在编译器的命令上,但没有详细说明如何强制执行)。 / p>

您需要查看编译器工具链的特定于实现的内容。它可以提供#pragma pack(或align或其他一些东西),您可以将其添加到结构定义中。

它也可以将其作为语言扩展提供。例如,gcc允许您向定义添加属性,其中一个属性控制对齐:

struct mystruct { int val[7]; } __attribute__ ((aligned (16)));

答案 3 :(得分:3)

你也许可以做一个双结构,将你的实际结构包装在第二个可以添加填充的结构中:

struct payload {
  int a;    /*Your actual fields. */
  float b;
  char c;
  double d;
};

struct payload_padded {
  struct payload p;
  char   padding[16 * ((sizeof (struct payload) + 15) / 16)];
};

然后你可以使用填充结构:

struct payload_padded a;

a.p.d = 43.3;

当然,您可以利用结构的第一个成员从结构开始的0字节开始的事实,并将指针视为struct payload_padded,就像它是指向{{1}的指针一样(因为它是):

struct payload