メモリ位置合わせの計算方法について

3794 ワード

自然配置
ナチュラルアライメントとは、各タイプのナチュラルアライメントであり、各タイプの変数のメモリアドレスは、そのタイプ自体の整数倍であり、構造体はメンバーの最長長タイプの整数倍である必要があります.
理由と意味の位置合わせ
メモリバイトの位置合わせの原因と意味については、ネット上の資料では大きく2つの言い方がある.プラットフォームの理由:すべてのプラットフォームが任意のアドレスのデータにアクセスできるわけではありません.一部のハードウェアプラットフォームでは、特定のタイプのデータしか取得できません.そうしないと、例外が放出されます.2.性能の原因:簡単に言えば空間で時間を取り替える.アクセスメモリでは、整列したメモリにアクセスするには1サイクルしかかかりませんが、整列していないメモリにアクセスするには2サイクルかかります.
メモリの位置合わせ
一般的なメモリ配置は、構造体やクラスでよく見られます.この文書は構造体を例に挙げます.構造体データの整列とは、構造体内の各データの整列を指す.構造体の最初のメンバーのヘッダアドレスは、構造体全体の変数のヘッダアドレスに等しく、その後のメンバーのアドレスは、宣言された順序と実際に使用されるバイト数とともに増加します.全体の構造体サイズを揃えるために、構造体に実際の意味のない文字を挿入して構造体を埋めます.使用についてalignがメモリの位置合わせを行う方法は,ここでは学習討論を行わず,次回に補完する.
構造体では、メンバーデータの整列は、*構造体の最初のメンバーのヘッダアドレス、すなわち構造体変数のヘッダアドレスを満たす.*構造体の各メンバーのヘッダアドレスの構造体のヘッダアドレスに対するオフセット量(offset)は、そのメンバーのデータ型サイズの整数倍です.*構造体の総サイズは、整列モジュール数(整列モジュール数は、#pragma pack(n)で指定されたnと構造体の最大データ型のメンバーサイズの最小値に等しい)の整数倍である.次に、具体例として、構造体の位置合わせ方法とその大きさの計算を行う.
以下の試験環境はwin 10 64ビットシステム+GNU 4である.9.2まず、C++とCのそれぞれのデータ型の大きさをテストし、結果は以下の通りである.
次に、構造体の大きさの計算を行い、構造体における変数宣言の順序が構造体の大きさに影響する場合がある.
まず、構造体には内蔵タイプのデータ構造のみが含まれています.
struct A
{
  int a;
  double b;
  short a;

};
struct B
{
  int b;
  short a;
  double c;  
};

次にmain関数に2つの構造体のサイズを出力します
cout << "sizeof(A) is " << sizeof(A) << endl;
cout << "sizeof(B) is " << sizeof(B) << endl;

出力結果がそれぞれ24と16の場合、shortを削除したり、コメントを削除したりします.実行後の結果はいずれも16.構造体Aの大きさは変わるが、構造体Bの大きさは同じであることがわかる.どうしてですか.
なぜなら、メモリ整列中の構造体の整列規則構造体の各メンバーのヘッダアドレスの構造体のヘッダアドレスに対するオフセット量(offset)は、そのメンバーデータ型サイズの整数倍であるからである.このルールは最初は分かりにくいかもしれませんが、先に上記の4つの例について説明します.最初は、構造体Aには3つの変数があり、メモリに格納される方式は、aが4バイト、bが8バイト、cが2バイトである.|aaaa------||bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbもうわざわざ修正しません.bbbbaa- -| |cccccccc|
一方、shortに注釈を付けた後、AとBのメモリ格納方式はそれぞれ以下の通りである:|aaaa----|bbbbbbb|と|bbb---|ccccc|
次に構造体に配列が含まれている場合
struct A
{
  int a;
  double b;
  char c[15];

};

構造体Aの宣言は以上のように、sizeof(A)=32である.cの大きさを17に変更するとsizeof(A)=40になります.以上の結果から,配列を含む場合,配列を複数の変数として計算するだけでよいことが分かる.
構造体に基本的なタイプの討論しか含まれていない後、構造体のネストの状況をテストする.
struct A
{
  char a;
  double b;
};

struct B
{
  int b;
  short a;
};

構造体A,Bの宣言は以上のとおりである.構造体Cの宣言は次のようになる.
struct C
{
  char c;
  A a;
};
struct C
{
  B b;
  char c;
};
struct C
{
  B b;
  char c;
  A a;
};

上記3つの場合、sizeof(C)の大きさはそれぞれ24,12,32である.メモリの割り当ては、|c------||a------||bbbbbbbb|の3つです.
|bbbb| |aa - -| |c - - -|
|bbbbaa - -| |c - - - - - - -| |a - - - - - - -| |bbbbbbbb|
3つ目のケースでは、構造体Bのメモリ位置は、そのメンバーの最大値に準拠するため、1行(すなわち、サイズ8)に変更されます.すなわち、Aのdouble b.
以上!間違いがあれば、交流を指摘してください.