1

コードに次の構造があります。

struct BlockDescriptor
{
    struct BlockDescriptor * pNext;
    bool _isFree;
};

そして、そのサイズは 4 + 1 = 5 (ポインターと1の場合は 4 bool) であると信じがちですが、何らかの理由でsizeof(struct BlockDescriptor)8 が返されます。誰かが理由を教えてもらえますか?

5 が 4 の倍数に切り上げられるのはパッキングの問題のためですか (32 ビットがほとんどのコンピューターで最も快適であるため)、実際のサイズを使用するように強制する方法はありますか (それが実際に正しい場合)サイズ) ?

4

3 に答える 3

1

のデータ メンバーはstructデフォルトで整列されています。これらのデータ メンバー間にパディングがある場合や、最後のデータ メンバーの後にパディングがある場合があります。あなたの場合、パディングは最後にある可能性が最も高くなります。

最初のデータ メンバーはポインタで、この場合は 4 バイトのメモリが必要です。次に、他のメンバーはchar1バイトのメモリしか必要としないaですが、4の倍数までのパディングがありますが、その理由は、あなたが言うように「ほとんどのコンピューターが最も快適に使用できるのは32ビットだから」4ではなく、最大のデータ メンバーのサイズです。

通常、使用可能なカスタム アラインメントを指定できるプラグマ ディレクティブがあります。Visual Studio には#pragma pack、この場合に役立つ可能性のある があります。自分が何をしているのかを知っていることを確認してください。メモリ使用量を最小限に抑えますが、コードのパフォーマンスに悪影響を及ぼす可能性があります。

詳細については、関連する質問をご覧ください:
構造体型のメモリ使用量を最小限に抑えるには?
sizeof は構造体のサイズをどのように計算し
ますか? 構造体のサイズは、その構造体のアラインメントの正確な倍数である必要がありますか?
またはそのメンバーに関連して C/C++ 構造体のアラインメントを決定する

于 2013-03-17T22:23:35.440 に答える
0

CPUがメモリにアクセスしてデータアイテム(または構造体メンバー)をフェッチすると、実際にはメモリコントローラに要求が送信され、メモリコントローラは、DRAMを適切に構造化されたデータストアのように見せるためのトリックを実行します。実際には、DRAMはセルの集まりであり、それぞれNビットのM行に配置されています(Nは1000程度になる可能性があります)。

ほとんどのアーキテクチャが一度に4、8、16、または32(またはそれ以上)のビットを処理することを知っているので、メモリコントローラは4の倍数のアドレスからのフェッチ用に最適化されています。アドレスabcd1002から1バイトをフェッチするとどうなりますか?さて、メモリコントローラはアドレスabcd1000から4バイトをフェッチし、それらをシフトして3番目のバイト(0、1、2であることを忘れないでください)を取得し、お粗末な非整列バイトを提供します。したがって、整列されたアドレスからのフェッチは、整列されていないアドレスからのフェッチよりも常に高速です。

この事実を認識しているコンパイラは、データ構造をパディングしてメモリに適した方法でレイアウトすることにより、速度を積極的に最適化します。

それがこの問題に関する重要なコンピュータアーキテクチャの視点を提供することを願っています。現在の回答ではこれについて言及されていなかったため、0.02ドルを追加したいと思いました。

于 2013-03-17T22:47:45.953 に答える
0

回答の投稿:Luka Rahne and cnicutar

pNextと_isFreeの間にパディングがあります。コンパイラ固有のメカニズムを介して「パッキング」を強制できます。構造体定義の前に#pragmapack(1)を配置します。

于 2013-03-17T22:10:12.417 に答える