sizeofを使用してクラスオブジェクトが占める空間サイズを計算する

1901 ワード

最初のセグメントコード:
#include 
using namespace std;

class s{
	char c1;
	
	char c2;
	int a;
};

int main(){
	cout<

第2セグメントコード
#include 
using namespace std;

class s{
	char c1;
	int a;
	char c2;

};

int main(){
	cout<

この2つのプログラムは結果が同じように見えますが、sizeof(s):6ですが、実は間違っています.1番目のセグメントの結果はsizeof(s):8、2番目のセグメントの結果はsizeof(s):12です.
次に分析してみましょう.
ここでは、メモリ内のデータの位置に関係するバイト位置合わせという概念に関し、変数のアドレスがその長さの整数倍にある場合、自然位置合わせと呼ばれます.例えば32ビットcpuでは、アドレス0 x 0000000004から整数変数が格納されると仮定すると、それは自然に整列する.どうしてそうなの?32ビットcpuは毎回サブ32 bitのデータ、つまり4 byte、つまり最初は0 x 00000000、0 x 000001、0 x 000002、0 x 0000003の4つのアドレスのデータが一気にcpuに読み込まれることを知っているので、次に0 x 0000004~0 x 0000007がちょうど記憶されているのがint型のデータ(int型データは4バイトじゃないですか?あ、ここで私が言っているのは一般的なint型ですが、一部のシステムではint型が4バイトではない)なので、このint型を取るときも一気に取ります.
しかし、このint型変数の最初のアドレスが0 x 0000004ではなく0 x 0000005であれば、1つのbyteの部分が0 x 0000008というアドレスに格納されますが、このbyteはcpuの次の数を取るまで待たなければなりません.つまり、このint型データを完全に取るには、2回取らなければなりません.しかも2回取り出した結果をつなぎ合わせて、完全なintに復元しなければならないので、時間の無駄ではないでしょうか.したがって、コンパイラは時間を節約するためにバイトを整列しますが、これは空間で時間を変える方法であり、上記の結果をもたらします.
次に、バイトの位置合わせの4つの重要な基本概念を見てみましょう.
1.データ型自体の位置合わせ値:
char型データの場合、自己整列値は1、short型の場合は2、int、float、double型の場合、自己整列値は4、単位バイトです.
2.構造体またはクラスの自己整列値:メンバーの自己整列値が最も大きい値.3.位置合わせ値の指定:#pragma pack(value)の場合の位置合わせ値valueの指定.4.データ・メンバー、構造体、クラスの有効な位置合わせ値:自己位置合わせ値と指定された位置合わせ値のうちの値.
今やっと本題に戻りましたが、どうしてそんな結果になったのですか.最初の例では、まずメモリに1つのcharを格納し、1バイトを占有し、もう1つのcharを格納し、また1バイトを格納します.今intが来ました.前のcharに続くと、2 byteが次の取数サイクルに行きます.その後、それらをつづる必要があります.面倒ですね.したがって、コンパイラは、現在の取数周期に残っている2つの空き記憶空間(冗談ですが、コンパイラはどうしてそれらを気にしないのですか.コンパイラは2つの充填字を入れます)にかかわらず、intを下の取数周期に直接入れます.これにより、接合体全体が4バイトの空間を占めます.
では、2つ目はなぜ違うのでしょうか.ストレージを申請する順番が変わったので、まずcharで、それからintで、最後にcharです.
まだわからない場合は、足を運んでくださいhttp://blog.csdn.net/21aspnet/article/details/6729724ああ、この大牛はもっと全面的に詳しく話しています.一番肝心なのは最後に図があります.