c - malloc 和 C 对齐 : is this hand-made optimization safe?

标签 c memory-alignment

我放置了整个代码,但当然,它位于不同的文件中(.h.c 文件)

typedef unsigned char ubyte;
typedef unsigned int uint;
#include<stdbool.h>

typedef struct Cube {
    ubyte n;
    ubyte e;
    ubyte s;
    ubyte w;
} Cube;

typedef struct Piece {
    Cube c;
    bool is_main;
    char offset_n;
    char offset_s;
} Piece;

typedef struct Block {
    ubyte total;
    Piece* pieces;
} Block;

Block *block_create(uint nb_pieces) {
    Block *block = malloc(sizeof(Block) + (sizeof(Piece) * nb_pieces));
    block->pieces = (Piece *) (&block + sizeof(Block));
    return block;
}

我只是想知道这行代码:block->pieces = (&block + sizeof(Block));是否始终安全。我的意思是:我们能否确定,在 sizeof(Piece) 之后,我们将立即得到 (sizeof(Piece) * nb_pieces) ?我们确定永远不会出现对齐问题吗(即,如果是 64 位对齐,sizeof(Block) 的内存将小于 8 个字节,并且 block->pieces 不应该精确指向 sizeof(Block),而是“sizeof(Block) 64 位对齐”。

我希望我说得足够清楚。

最佳答案

首先,这没有达到您的预期,并且出于多种原因:

block->pieces = (&block + sizeof(Block));

首先,&block是变量block的地址,而不是block的内容,并且类型为block ** 。最多,您可以安全地为该指针值添加 1,因为更多的值将创建一个超出该变量末尾的指针,这是无效的。

那么您需要将 &block 更改为 block。这仍然不会达到您的预期,因为指针算术会将原始地址增加对象大小的倍数。因此,添加 sizeof(Block) 并不是向上移动 1 个数组元素,而是向上移动 sizeof(Block) 数组元素。

要解决此问题,您需要block + 1。现在您需要开始担心对齐问题。为了使 Pieces 数组正确对齐,您需要检查 _Alignof(Block)_Alignof(Piece) 是否相同。如果没有,您需要添加填充字节:

int padding = 0;
if (_Alignof(Block) % _Alignof(Piece) != 0) {
    padding = _Alignof(Piece) - (_Alignof(Block) % _Alignof(Piece));
}
Block *block = malloc(sizeof(Block) + padding + (sizeof(Piece) * nb_pieces));
block->pieces = (Piece *)((char *)(block + 1) + padding);

当然,您可以通过将 pieces 成员设为灵活数组成员来避免这一切:

typedef struct Block {
    ubyte total;
    Piece pieces[];
} Block;

并且分配本身就足够了。

关于c - malloc 和 C 对齐 : is this hand-made optimization safe?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71451305/

相关文章:

"Empty classes"的 C++ 多重继承内存布局

C++:分配对齐矩阵

c - 是否有明确的curses菜单库(menu.h)引用?

c - 在 C 中访问字符指针字符串中的特定字符

c - 数组元素也是按值传递还是按引用传递?

c++ - "points to uninitialised byte(s)"Valgrind 错误

c - 在 C 中使用 scanf 检测新行

c - PPM 中显示的矩形中的 4 个三角形

c++ - 数据对齐以实现矢量化/高效缓存访问

c++ - 如何以独立于平台的方式设置对齐方式?