C结构大小对齐

Neo*_*cer 8 c struct alignment

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

VHa*_*avy 13

对于Microsoft Visual C++:

#pragma pack(push, 16)

struct _some_struct
{
     ...
}

#pragma pack(pop)
Run Code Online (Sandbox Code Playgroud)

对于GCC:

struct _some_struct { ... } __attribute__ ((aligned (16)));
Run Code Online (Sandbox Code Playgroud)

例:

#include <stdio.h>

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

int main()
{
    printf("%lu\n", sizeof(struct test_t));
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

gcc -o main main.cwill输出编译16.其他编译器也是如此.

  • 这是真的(暗示).自己检查一下.我用一个例子更新了我的答案. (3认同)
  • 对于 gcc __attribute__ 对齐,它实际上强制结构大小为 16B 的倍数吗?或者它只是保证结构体的起始地址与 16B 对齐? (2认同)
  • 是的它是:) ..我的坏 (2认同)

Ric*_*ers 6

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

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

所以,如果你有这样的结构.

struct _simpleStruct {
   int iValueA;
   int iValueB;
};
Run Code Online (Sandbox Code Playgroud)

然后你可以做类似以下的事情.

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

这样做的目的是在你担心的情况下将大小提升到下一个16字节大小.但是,内存分配器可能会或可能不会为您提供实际大小的块.内存块实际上可能比您的请求大.

如果你打算对此做一些特别的事情,比如说你打算把这个结构写到一个文件中,你想知道块大小那么你必须在malloc()中使用相同的计算而不是使用sizeof()运算符来计算结构的大小.

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

#define SIZEOF16(x) ((sizeof(x)/16 + 1) * 16)
Run Code Online (Sandbox Code Playgroud)

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


pax*_*blo 5

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

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

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

struct mystruct { int val[7]; } __attribute__ ((aligned (16)));
Run Code Online (Sandbox Code Playgroud)