我把整個代碼,但是,當然,它在不同的檔案(.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 位對齊”)。
我希望我足夠清楚。
uj5u.com熱心網友回復:
首先,這并沒有達到您的預期,并且有多種原因:
block->pieces = (&block sizeof(Block));
首先,&block是變數的地址block,而不是 的內容block,并且具有型別block **。最多,您可以安全地添加 1 this 指標值,因為任何更多內容都會在此變數的末尾創建一個無效的指標。
因此,您需要更改&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;
并且分配本身就足夠了。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/441809.html
