C结构大小对齐
我希望C结构的大小是16个字节的倍数(16B / 32B / 48B / ..)。 它到达的大小无关紧要,它只需要16B的倍数。 我怎么能强制编译器这样做? 谢谢。
C结构的大小取决于结构的成员,它们的类型以及它们的数量。 实际上没有标准方法可以强制编译器使结构变为某个大小的倍数。 有些编译器提供了一个pragma,它允许你设置对齐边界,但这实际上是另一回事。 并且可能有一些会有这样的设置或提供这样一个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)
据我所知,没有可靠的方法从指针中提取已分配块的大小。 通常,指针将具有内存堆管理function使用的内存分配块,该内存堆管理function将包含各种内存管理信息,例如分配的块大小,实际上可能大于请求的内存量。 但是,此块的格式以及它相对于提供的实际内存地址的位置取决于C编译器的运行时间。
对于Microsoft Visual C ++:
#pragma pack(push, 16) struct _some_struct { ... } #pragma pack(pop)
对于GCC:
struct _some_struct { ... } __attribute__ ((aligned (16)));
例:
#include 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
。 其他编译器也是如此。
这完全取决于编译器和其他工具,因为未在ISO C标准中明确指定对齐(它指定对齐可能发生在编译器的命令上,但没有详细说明如何强制执行)。
您需要查看编译器工具链的特定于实现的内容。 它可以提供一个#pragma pack
(或者align
或其他一些东西),你可以添加到你的结构定义中。
它也可以将其作为语言扩展。 例如,gcc允许您向定义添加属性,其中一个属性控制对齐:
struct mystruct { int val[7]; } __attribute__ ((aligned (16)));
你也许可以做一个双结构,将你的实际结构包装在第二个可以添加填充的结构中:
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; apd = 43.3;
当然,您可以利用结构的第一个成员从结构开始的0字节开始的事实,并将指向struct payload_padded
的指针视为指向struct payload
的指针(因为它是):
float d_plus_2(const struct payload *p) { return p->d + 2; } /* ... */ struct payload_padded b; const double dp2 = d_plus_2((struct payload *) &b);