C構造体のサイズを16バイト(16B/32B/48B/..)の倍数にします。 どのサイズになるかは関係ありませんが、16Bの倍数である必要があります。 これを行うにはどのようにコンパイラを強制できますか?おかげさまで C構造体のサイズの整列
答えて
C構造体のサイズは、構造体のメンバー、型、およびその数によって異なります。実際には、構造体をいくつかのサイズの倍数にするようコンパイラーに強制する標準的な方法はありません。コンパイラの中にはプラグマが用意されているものもありますが、これは実際には異なるものですが、境界の境界を設定することができます。そのような設定をしたり、そのようなプラグマを提供するものがあるかもしれません。
しかし、この1つの方法は、構造体のメモリ割り当てを行い、メモリ割り当てを強制して次の16バイトサイズにすることです。
このような構造体があれば、
struct _simpleStruct {
int iValueA;
int iValueB;
};
次に、次のようなことができます。
{
struct _simpleStruct *pStruct = 0;
pStruct = malloc ((sizeof(*pStruct)/16 + 1)*16);
// use the pStruct for whatever
free(pStruct);
}
これは、あなたが懸念していた限り、サイズを次の16バイトサイズにプッシュすることです。しかし、メモリアロケータは実際にはそのサイズのブロックを与えるかもしれないし、そうでないかもしれません。メモリのブロックは、実際にあなたの要求よりも大きいかもしれません。
このような特別な処理を行う場合、たとえば、この構造体をファイルに書き込む場合、ブロックサイズを知りたい場合は、同じ構造体で使用されているのと同じ計算を行う必要があります。 sizeof()演算子を使用して構造体のサイズを計算するのではなく、malloc()を使用します。
したがって、次のようなマクロを使用して独自のsizeof()演算子を記述します。
#define SIZEOF16(x) ((sizeof(x)/16 + 1) * 16)
私が知る限り、割り当てられたブロックのサイズをポインタから引き出すための信頼できる方法はありません。通常、ポインタには、割り当てられたブロックサイズなどのさまざまなメモリ管理情報を含むメモリヒープ管理関数によって使用されるメモリ割り当てブロックがあります。このサイズは、実際には要求されたメモリ量よりも大きい場合があります。ただし、このブロックのフォーマットと、実際のメモリアドレスとの相対的な位置は、Cコンパイラの実行時間によって異なります。
あなたは[malloc()の戻り値をCでキャストしてはいけません(http://stackoverflow.com/a/605858/28169)。 – unwind
これは、ISO C標準の深い位置合わせが指定されていないため(コンパイラーにはアライメントが起こるかもしれないが、実装方法については詳しくは述べられていない)、アライメントが指定されていないため、
コンパイラのツールチェーンには、実装固有のものを調べる必要があります。構造定義に追加できる#pragma pack
(またはalign
またはその他のもの)を提供することがあります。
これは言語拡張機能として提供される場合もあります。例えば、GCCは、あなたは、アライメントを制御しそのうちの一つの定義に属性を追加することができます:
struct mystruct { int val[7]; } __attribute__ ((aligned (16)));
のMicrosoft Visual C++の場合:GCCの場合
#pragma pack(push, 16)
struct _some_struct
{
...
}
#pragma pack(pop)
:
struct _some_struct { ... } __attribute__ ((aligned (16)));
例:
#include <stdio.h>
struct test_t {
int x;
int y;
} __attribute__((aligned(16)));
int main()
{
printf("%lu\n", sizeof(struct test_t));
return 0;
}
gcc -o main main.c
と入力すると、16
が出力されます。他のコンパイラも同様です。
gcc __attribute__が整列している場合、実際に構造体のサイズを16Bの倍数に強制していますか?それとも、構造体の開始アドレスが16Bに揃っていることを保証するだけですか? –
構造の開始アドレスとサイズの両方が16Bに揃えられます。これは、構造体の配列の要素の正しい位置合わせを保証するために行われます。 – Romeo
これは当てはまりません。 __attribute(aligned(x)))マクロは、構造体をxバイト境界に割り当て、構造体のサイズとは何も関係ありません。 http://gcc.gnu.org/onlinedocs/gcc-3.2.3/gcc /Variable-Attributes.html –
あなたはおそらくパディングを追加することができます秒1であなたの実際の構造体を包む、二重の構造体を行うことができます:
struct payload {
int a; /*Your actual fields. */
float b;
char c;
double d;
};
struct payload_padded {
struct payload p;
char padding[16 * ((sizeof (struct payload) + 15)/16)];
};
次に、あなたがパディング構造体を操作できます。もちろん
struct payload_padded a;
a.p.d = 43.3;
構造の最初のメンバーが構造体の開始位置から0バイトを開始し、ポインタがstruct payload
へのポインタであるかのようにstruct payload_padded
を扱うことを利用できます。
float d_plus_2(const struct payload *p)
{
return p->d + 2;
}
/* ... */
struct payload_padded b;
const double dp2 = d_plus_2((struct payload *) &b);
- 1. C構造体の整列
- 2. CLRシーケンシャル構造体レイアウト:整列とサイズ
- 3. Visual C++での構造体の整列
- 4. Cの構造体のサイズ
- 5. 構造体の整列したメンバーとのC++の整列
- 6. Objective-CとC++の構造体のサイズ
- 7. C/C++ qsort構造体内の構造体の配列
- 8. C++の構造体のフィールドのサイズ
- 9. C:データ構造の整列
- 10. C#で構造体の配列を整列する方法は?
- 11. C++の構造体内の構造体
- 12. C構造体内の構造体内部の構造体
- 13. 整列12バイトの構造体CUDA
- 14. 配列を含む構造体のサイズ
- 15. 構造体のサイズ12、構造体のオブジェクトを8に整列できますか?
- 16. C構造体の整列とコンパイラ間の移植性
- 17. Visual C++ 2008での構造体の整列
- 18. C++からC#への配列フィールドを含む構造体の整列配列
- 19. Cで2d構造体の配列を整理する問題
- 20. 後で構造体型の配列サイズを指定する(C++)
- 21. 構造体の配列 - 構造体?
- 22. C構造体と配列
- 23. バイト配列のC++構造体をc#
- 24. Cの構造体の動的配列の構造体の動的配列
- 25. 構造体のC配列のcythonメモリビュー
- 26. 構造体へのポインタのC配列
- 27. Cの構造体宣言の配列
- 28. C#からネイティブC++への構造体の2次元配列の整理
- 29. C - 構造体
- 30. C構造体
コンパイラとは何ですか? – Joe
あなたのタイトルは単語の整列を使用しますが、質問の本文は構造体のサイズについて語ります。あなたは実際に何を達成したいのですか?そして、なぜ私はまた興味があります。 –
ここでは、ユニオンを使用して特定のサイズにパッドするソリューションを提供する既存の記事です。しかし、その解決策は構造体[Size of Struct](http://stackoverflow.com/questions/8705665/force-specific-struct-size-in-c)のサイズを知る必要がありますが、あなたがする必要があるのは、数値定数ではなく、(sizeof(struct it)/ 16 + 1)* 16のようなchar配列のサイズ計算。 –