ディレクトリ
位置合わせを変更するコンパイラを強制するの#pragmaパック(X)
sizeof特定のアプリケーションシナリオ
- ユニットは占有型バイトのメモリ空間のオブジェクトを表示します。
- オブジェクトを動的に割り当てられたときは、システムが割り当てるためにどのくらいのメモリを知らせることができます。
- (ウィンドウ、Pythonなど)いくつかのプラットフォーム上で簡単に拡張の種類によっては、直接の間で、この変数のプロパティのプロパティとして、変数、メモリに格納された変数の数を作成します。
- あなたが状況にリアルタイム観察と記録のsizeofメモリを使用できるように、いくつかのオペランドの使用時では、リアルタイムの変化があるでしょう。
- オブジェクトはsizeofを行う、または関数パラメータが配列されている場合は、直接そのポインタのsizeofサイズを返します。
一般的なデータ型サイズ
- int型:4ビット
- 短いタイプ:2ビット
- ロングタイプ:4ビット
- char型:1ビット
- ダブルタイプ:8ビット
- bool型:1ビット
- float型:4ビット
- ポインタ型:4ビット
- タイプString: "文字列str [] =" こんにちは ";" 最後に長さを追加し、(最後があるため、 "\ n" はプレースホルダシンボルが存在する)、(= 6 5 + 1)
つまり、それらのほとんどは8ビット(double型)である最長のうち4ビット、であり、最小は1ビット(CHARおよびブール値)です。
オブジェクトクラスが占めるスペースの大きさ
私たちは、最初にすべての変数が代わりに来るように計算パディング方式を使用するのでは、単純なクラスが来る蓄積するではないの後に、オブジェクトのクラスのサイズが作成され、一つのことを理解しなければなりません!
クラスサイズは、その内部のメンバーの最大要素サイズの整数倍でなければならないデータがクラスに格納されているときに、データメンバーがされた後(本質的に、オフセットに記憶された第1のデータのメンバーは、その後、0場所でありますこれは、部材のサイズの整数倍の貯蔵)の開始後に開始位置から格納されています。
#include <stdio.h>
#include <iostream>
class A
{
public:
int i;
};
class B
{
public:
char ch;
private:
};
class C
{
public:
int i;
short j;
private:
};
class D
{
public:
int i;
short j;
char ch;
private:
};
class E
{
public:
int i;
int ii;
short j;
char ch;
char chr;
private:
};
class F
{
public:
int i;
int ii;
int iii;
short j;
char ch;
char chr;
private:
};
int main()
{
printf("sizeof(int) = %d\n", sizeof(int));
printf("sizeof(short) = %d\n", sizeof(short));
printf("sizeof(char) = %d\n", sizeof(char));
printf("sizeof(A) = %d\n", sizeof(A));
printf("sizeof(B) = %d\n", sizeof(B));
printf("sizeof(C) = %d\n", sizeof(C));
printf("sizeof(D) = %d\n", sizeof(D));
printf("sizeof(E) = %d\n", sizeof(E));
printf("sizeof(F) = %d\n", sizeof(F));
system("pause");
return 0;
}
次のように実行します。
クラスは、:INT->のsizeof(A)=はsizeof(INT)= 4。
含むクラスB:A char->のsizeof(B)=はsizeof(CHAR)= 1。
クラスCは:int型(4バイト)+1短い(2バイト) - >はsizeof(C)= 4 + 2 = 6、6、8を得、したがって、2の補数、4の整数倍ではないからです。
クラスDであってINT(4バイト)+1短い(4バイト)+1 CHAR(1バイト) - >はsizeof(D)= 4 +(2 + 1)= 7、7がないようです4の整数倍なので、1つのアップ8を得たこと。
クラスE:+ 4 4 + 2 + 1 + 1 = 12は、12を得るために、4の整数倍です。
クラスF:4 + 4 + 4 + 2 + 1 + 1 = 16は、16を得るために、4の整数倍です。
決意の結果、及びので、それが可能な場合ではない場合に最大加数の整数倍となって、最小数を補うために、最大加数の整数倍とされていない、確認するために結果を追加します。
スペース含むオブジェクトクラスの仮想関数のサイズ
同等で、クラスの数は仮想関数を持っているので、こと、正常な機能は、メモリを占有しませんが、限り、仮想関数があるとして、それはポインタのメモリサイズ(仮想関数テーブルの仮想関数である理由が含まれています)占有します複数の変数のポインタ(4バイト)。
以下は、継承機能の2セットは、タリア非常に明らかな違いなしに、仮想関数で設定されています。
#include <stdio.h>
#include <iostream>
using namespace std;
class Base
{
public:
Base(int x) :a(x)
{
}
void print()
{
printf("base\n");
}
private:
int a;
};
class Derived:public Base
{
public:
Derived(int x) :Base(x - 1), b(x)
{
}
void print()
{
printf("derived\n");
}
private:
int b;
};
class A
{
public:
A(int x) :a(x)
{
}
virtual void print()
{
printf("A");
}
private:
int a;
};
class B:public A
{
public:
B(int x) :A(x - 1), b(x)
{
}
virtual void print()
{
printf("B");
}
private:
int b;
};
int main()
{
Base obj1(1);
printf("sizeof(Base obj1):%d\n", sizeof(obj1));
Derived obj2(2);
printf("sizeof(Base obj2):%d\n", sizeof(obj2));
A a(1);
printf("sizeof(A a):%d\n", sizeof(a));
B b(2);
printf("sizeof(B b):%d\n", sizeof(b));
system("pause");
return 0;
}
次のようにx86の環境でコンパイルされ、結果は予想に沿ったものであることに留意すべきです。
INTを有するベース、オブジェクトのサイズが作成されるように、基本クラス4バイトのために、INTの型を持つ派生するため、このクラスベースから継承上ので、ベースに基づいて、4を追加していることすなわち、8バイト。
同様に、Aは、+ 4 4(+仮想関数型をINT)= 8である場合、(この時点では、仮想関数ではないが、カウントが仮想関数の4つの単語ではないように、と呼ばれるに基づいてA、次にBセクション)も添加し、仮想関数int型:4 + 4 + 4 = 12。
しかし、それは、x64ビットで実行されている場合:
結果は、前と(チェック後に残る特定の理由)と同じではありません。
注:このクラスはローカル変数に格納されている静的変数、静的クラス変数とメモリ空間が含まれている、一緒にメモリ空間に存在しないようならば、クラスは、使用のsizeofを計算するための静的変数が含まれている場合、あなたは何を見つけるんだろう静的変数のシェアの大きさを計算します。
sizeofとstrlenの違い
- これは、strlen関数、はsizeofオペレータである関数定義です。
- sizeofタイプは,,オブジェクトが最後に「0 \」でなければならないようなのsizeof(INT)として、パラメータとして使用されるが、唯一strlenをしないと、具体的にstrlenを(CHAR *)でSTRLEN文字列を測定することができます。
- パラメータのsizeofなどのアレイは、パラメータとして縮重へのポインタをポインタとして分解が、時間の関数ではない場合
- sizeofコンパイル時(オペレータのタイプであるように)が、(ストリング演算子の長さであるように)動作のみで結果をstrlenをしなければならない計算結果を出します。
- sizeof(INT)、それは可変である場合、の必要ブラケットがない:のsizeof使用時に、後者のタイプのものである場合、それは必要括弧ではsizeof、のsizeofは、オペレータではなく関数であるからです。
文字列の長さへのポインタが計算されている場合は、strlenをしなければなりません、
店舗への文字列配列
例えば:
#include <stdio.h>
#include <iostream>
using namespace std;
int main()
{
char str[20] = "0123456";
int a = sizeof(str);
printf("a:%d\n", a);
int b = strlen(str);
printf("b:%d\n", b);
system("pause");
return 0;
}
上記の障害が発生し、文字列の時間長の計算、strlenを使用することを必要とします。
文字列へのポインタ
#include <stdio.h>
#include <iostream>
using namespace std;
int main()
{
const char* ss = "0123456";
int a = sizeof(ss);
printf("a:%d\n", a);
int b = strlen(ss);
printf("b:%d\n", b);
system("pause");
return 0;
}
結果:
それを計算するために、またはに許可されていません、それはより多くの「\ 0」文字のでしょう使用はsizeof。
sizeofは、文字列の長さを計算するために使用することができない単語では、それはstrlenを使用することができます。
sizeof(STR)/はsizeof(STR [0])
このコマンドは、計算列str配列のすべての要素の数である、数は配列要素を計算することは有効ではありません、我々は明確に区別しなければなりません!
コモンウェルスサイズの計算
コモンウェルスに依存します。
- 空間の大きさのすべてのメンバーのサイズは、(ユニーク組合)の最大のメンバーの一人で占められ
- (同じ配向で、ユニオン、構造体、クラス)最大のメンバーの一員として、データタイプのアラインメントの長さの整数倍
次のコードを参照してください、
#include <stdio.h>
#include <iostream>
using namespace std;
union u0
{
int i;
double j;
};
union u1
{
char a[13];
int i;
};
union u2
{
char a[13];
char b;
};
int main()
{
printf("u0:%d\n", sizeof(u0));
printf("u1:%d\n", sizeof(u1));
printf("u2:%d\n", sizeof(u2));
system("pause");
return 0;
}
U0を見ては、(8)、二重の内側に、int型(4)、労働組合は、最大保存期間の種類に依存し、ありません、問題はありませんダブルの最大のタイプ、そして8、アライメントを見ていることは明らかです問題は、8 8の倍数です。
従って、タイプ(サイズ13)、及びINT(4バイト)として、最大再度、格納された13の種類を見つけるために、文字列、変数を有するルックU1、アライメントの原理、文字サイズ(1バイト)は、INTサイズが4であり、そして組合はSO 4の整数倍ラウンド、(+ 3 13)は= 16、サイズ4の整数倍であるべきです。(注アレイの特殊性、及び他の言葉で最小単位のサイズ、すなわち、タイムアラインメントを見るために、アレイの最小単位は1バイト文字です)
同様に、13であるU2、が、CHAR(1バイトa)にバイトの最大数、1は13に、13の整数倍であります
結果は以下の通りであります:
位置合わせを変更するコンパイラを強制するの#pragmaパック(X)
上記クラスC outは、通常の操作に応じて、Cのサイズが原因アラインメントに、8でなければならない(Cのクラスが含まれています:int型(4バイト)+1短い(2バイト) - >はsizeofを( C)= 4 + 2 = 6、6 4、従って、2の補数の整数倍ではないので、8を得ました;)。しかし、私はそうクラスの大きさは、それがライン上に蓄積されている変数の型クラスに直接なると、1に設定されている最小単位を揃えるために強制の#pragmaパック(1)を使用します!
#include <stdio.h>
#include <iostream>
using namespace std;
#pragma pack(1)
class C
{
public:
int i;
short j;
private:
};
int main()
{
printf("c:%d\n", sizeof(C)); //原来因为要对齐int类型,结果为8
system("pause");
return 0;
}