标签: memory-alignment

C结构中的内存对齐

我正在使用32位机器,所以我认为内存对齐应该是4个字节.说我有结构:

typedef struct {
    unsigned short v1;
    unsigned short v2;
    unsigned short v3;
} myStruct;
Run Code Online (Sandbox Code Playgroud)

实际大小是6个字节,我想对齐大小应该是8,但sizeof(myStruct)返回6.

但是,如果我写:

typedef struct {
    unsigned short v1;
    unsigned short v2;
    unsigned short v3;
    int i;
} myStruct;
Run Code Online (Sandbox Code Playgroud)

实际大小是10个字节,对齐是12,这次sizeof(myStruct) == 12.

有人可以解释一下有什么区别吗?

c c++ memory-alignment structure-packing

53
推荐指数
5
解决办法
4万
查看次数

使std :: vector分配对齐的内存

是否可以使用std::vector自定义结构分配对齐的内存以便使用SIMD指令进行进一步处理?如果有可能,有Allocator没有人碰巧有这样的分配器,他可以分享?

c++ memory-management memory-alignment allocator

48
推荐指数
3
解决办法
2万
查看次数

malloc如何理解对齐?

以下摘录自此处

pw = (widget *)malloc(sizeof(widget));
Run Code Online (Sandbox Code Playgroud)

分配原始存储.实际上,malloc调用分配的存储空间足够大并且适当地对齐以容纳类型为widget 的对象

他还说,从草本植物中看到快速的pImpl,他说:

对齐.任何内存对齐.保证通过new或malloc动态分配的任何内存都可以正确地对齐任何类型的对象,但是没有动态分配的缓冲区没有这样的保证

我对此感到好奇,malloc如何知道自定义类型的对齐方式?

c c++ memory-alignment

47
推荐指数
3
解决办法
2万
查看次数

对于所有对象类型T,sizeof(T)> = alignof(T)总是这样吗?

对于任何对象类型T,它总是sizeof(T)至少与大小一样大alignof(T)吗?

直观地看起来如此,因为即使你调整对象的对齐方式,例如:

struct small {
  char c;
};
Run Code Online (Sandbox Code Playgroud)

通常情况下,它们的"大小"也会向上调整,以便在保持对齐的同时,阵列中对象之间的关系是有意义的(至少在我的测试中.例如:

struct alignas(16) small16 {
  char c;
};
Run Code Online (Sandbox Code Playgroud)

两者的大小和对齐都是16.

c++ memory-alignment c++11 alignof

42
推荐指数
4
解决办法
2259
查看次数

类/结构成员总是按照它们被声明的顺序在内存中创建吗?

这是Rob Walker 在这里回答的问题.

假设我声明一个类/结构,如下所示:

struct
{ 
    char A;
    int B;
    char C;
    int D;
};
Run Code Online (Sandbox Code Playgroud)

是否可以安全地假设这些成员将在内存中以完全相同的顺序声明,或者这是否依赖于编译器?我问,因为我一直认为编译器可以随心所欲地做任何事情.

这导致了我的下一个问题.如果上面的例子导致内存对齐问题,为什么编译器不能只是隐式地将它变成这样的东西:

struct
{ 
    char A;
    char C;
    int B;
    int D;
};
Run Code Online (Sandbox Code Playgroud)

(我主要是询问C++,但我也有兴趣听到C答案)

相关话题

c++ memory memory-alignment

41
推荐指数
1
解决办法
1万
查看次数

为什么 argc 和 argv 的地址相差 12 个字节?

我在我的计算机(运行 Linux 的 64 位 Intel)上运行了以下程序。

#include <stdio.h>

void test(int argc, char **argv) {
    printf("[test] Argc Pointer: %p\n", &argc);
    printf("[test] Argv Pointer: %p\n", &argv);
}

int main(int argc, char **argv) {
    printf("Argc Pointer: %p\n", &argc);
    printf("Argv Pointer: %p\n", &argv);
    printf("Size of &argc: %lu\n", sizeof (&argc));
    printf("Size of &argv: %lu\n", sizeof (&argv));
    test(argc, argv);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

该程序的输出是

$ gcc size.c -o size
$ ./size
Argc Pointer: 0x7fffd7000e4c
Argv Pointer: 0x7fffd7000e40
Size of &argc: 8
Size of &argv: 8
[test] Argc …
Run Code Online (Sandbox Code Playgroud)

c memory-alignment

40
推荐指数
2
解决办法
2581
查看次数

对齐对C++ 11的性能是否真的重要?

对齐对C++ 11的性能是否真的重要?

在Stroustrup的书中有一条建议,要求从最大到最小的结构中对成员进行排序.但我想知道是否有人进行了测量,以确定是否会产生任何影响,并且在编写代码时是否值得考虑.

c++ memory-alignment c++11

38
推荐指数
2
解决办法
3756
查看次数

原子x86指令的对齐要求

Microsoft提供了InterlockedCompareExchange执行原子比较和交换操作的功能.还有一个内在的._InterlockedCompareExchange

在x86上,这些是使用lock cmpxchg指令实现的.

但是,通过阅读这三种方法的文档,他们似乎并不同意对齐要求.

英特尔的参考手册没有说明对齐(除了如果启用了对齐检查并且进行了未对齐的内存引用,则会生成异常)

我也查找了lock前缀,具体说明了这一点

锁定前缀的完整性不会受到内存领域的对齐方式.

(强调我的)

所以英特尔似乎认为对齐是无关紧要的.无论如何,这个操作都是原子的.

_InterlockedCompareExchange固有的文档也只字未提对齐,但是InterlockedCompareExchange 功能指出,

该函数的参数必须在32位边界上对齐; 否则,该函数将在多处理器x86系统和任何非x86系统上表现不可预测.

什么给出了什么?对齐要求是否InterlockedCompareExchange只是为了确保该功能即使在cmpxchg指令不可用的486之前的CPU上也能正常工作?这看起来很可能基于上述信息,但在依赖它之前我想确定一下.:)

或者ISA需要对齐以保证原子性,我只是在英特尔的参考手册中找错了地方?

x86 winapi atomic interlocked memory-alignment

37
推荐指数
2
解决办法
5202
查看次数

扩展填充结构时,为什么不能在尾部填充中放置额外的字段?

让我们考虑结构:

struct S1 {
    int a;
    char b;
};

struct S2 {
    struct S1 s;       /* struct needed to make this compile as C without typedef */
    char c;
};

// For the C++ fans
struct S3 : S1 {
    char c;
};
Run Code Online (Sandbox Code Playgroud)

S1的大小为8,由于对齐而预期.但是S2和S3的大小是12.这意味着编译器将它们构造为:

| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10| 11|
|       a       | b |  padding  | c |  padding  |
Run Code Online (Sandbox Code Playgroud)

编译器可以在不破坏对齐约束的情况下将c放在6 7 …

c c++ struct memory-alignment

37
推荐指数
2
解决办法
2370
查看次数

结构由编译器重新排序

假设我有这样的结构:

struct MyStruct
{
  uint8_t var0;
  uint32_t var1;
  uint8_t var2;
  uint8_t var3;
  uint8_t var4;
};
Run Code Online (Sandbox Code Playgroud)

这可能会浪费很多(不是很多)空间.这是因为uint32_t变量的必要对齐.

实际上(在对齐结构以便它实际上可以使用uint32_t变量之后)它可能看起来像这样:

struct MyStruct
{
  uint8_t var0;
  uint8_t unused[3];  //3 bytes of wasted space
  uint32_t var1;
  uint8_t var2;
  uint8_t var3;
  uint8_t var4;
};
Run Code Online (Sandbox Code Playgroud)

更有效的结构将是:

struct MyStruct
{
  uint8_t var0;
  uint8_t var2;
  uint8_t var3;
  uint8_t var4;
  uint32_t var1;
};
Run Code Online (Sandbox Code Playgroud)

现在,问题是:

为什么编译器禁止(按标准)重新排序结构?

如果对结构进行重新排序,我认为你没有任何方法可以用脚射击自己.

c c++ struct memory-alignment

34
推荐指数
6
解决办法
5639
查看次数