我在 C 中有结构:
typedef struct Node {
int data; // 4 bytes int + 4 bytes for alignment
struct Node* prev; // 8 bytes pointer
struct Node* next; // 8 bytes pointer
} Node;
该结构体的大小为 24 字节 (8 + 8 + 8)。当我使用 sizeof(Node) 时,编译器也显示 24 字节。
但是,当我在堆上创建两个或多个结构体(一个接一个)并查看它们的内存位置时,每个 Node 结构体之间有 8 个字节间隙。 例如:
11121344 (the 1st Node address)
11121376 (the 2nd Node address) // 376-344 = 32-24 = 8 extra bytes
11121408 (the 3rd Node address) // 408-376 = 32-24 = 8 extra bytes
你能解释一下为什么编译器通过在节点之间添加 8 个字节来分隔节点结构吗?
最佳答案
您的观察结果可能有两个原因:
- C 标准要求
malloc
始终返回具有最大对齐方式的内存块,以防止对齐问题,无论您分配什么内容。 malloc
通过使用某种数据结构在内部管理内存块。根据实现的不同,它会向每个内存块添加额外的信息以供内部使用。例如,malloc 可以管理链表中的内存块,那么它需要每个 block 保存一个指向下一个 block 的附加指针。
最大对齐取决于体系结构和编译器/malloc
- 使用的实现。
对于您的情况并假设 glibc,直接取自 glibc/malloc.c
的文档:
Alignment: 2 * sizeof(size_t) (default)
(i.e., 8 byte alignment with 4byte size_t). This suffices for
nearly all current machines and C compilers. However, you can
define MALLOC_ALIGNMENT to be wider than this if necessary.
Minimum overhead per allocated chunk: 4 or 8 bytes
Each malloced chunk has a hidden word of overhead holding size
and status information.
Minimum allocated size: 4-byte ptrs: 16 bytes (including 4 overhead)
8-byte ptrs: 24/32 bytes (including, 4/8 overhead)
因此,在您的情况下,malloc
将与 2 * sizeof(size_t) =
16 字节对齐。
另请注意提到的“隐藏开销”。此开销是由于存储用于内存管理的附加内部信息...
关于c - C 中结构之间的额外填充,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59713995/