• ベストアンサー

アドレスの計算が合わない

C++でポインタの勉強をしています。 その中でアドレスについての以下のような記述がありました。 <例1> struct { int a; int b; int c; } oshiete; cout << &oshiete.a << endl; cout << &oshiete.b << endl; cout << &oshiete.c << endl; このように、構造体の中で宣言された変数の領域は連続した場所を確保するというものでした。これの実行結果は以下の様になりました。 0013FF5C 0013FF60 0013FF64 int型のバイト数は4でしたので、それぞれの変数の先頭アドレスは4つ間隔になっています。しかし、これの2つ目の変数bをshort型に変えても同じ結果が返ってくるのです。short型のバイト数は2です。 <例2> struct { int a; short b; int c; } oshiete; cout << &oshiete.a << endl; cout << &oshiete.b << endl; cout << &oshiete.c << endl; 結果: 0013FF5C 0013FF60 0013FF64 そして変数aもshort型にすると、やっと納得のいく結果になりました。 <例3> struct { short a; short b; int c; } oshiete; cout << &oshiete.a << endl; cout << &oshiete.b << endl; cout << &oshiete.c << endl; 結果: 0013FF60 0013FF62 0013FF64 なぜ<例2>ではint, short, intの順で宣言したのにアドレスが全て4つ間隔なのでしょうか?例えば先頭アドレスが0013FF5Cであるなら、 0013FF5C 0013FF60 0013FF62 のように1つ目と2つ目のアドレス差は4、2つ目と3つ目のアドレス差は2になるはずだと思うのですが。

質問者が選んだベストアンサー

  • ベストアンサー
  • noocyte
  • ベストアンサー率58% (171/291)
回答No.4

↓詳しい説明 データ型のアラインメントとは何か,なぜ必要なのか? http://www5d.biglobe.ne.jp/~noocyte/Programming/Alignment.html

その他の回答 (4)

  • aris-wiz
  • ベストアンサー率38% (96/252)
回答No.5

>なぜ<例2>ではint, short, intの順で宣言したのに >アドレスが全て4つ間隔なのでしょうか? なぜ、こうなるかは他の方もおっしゃっていますが、 コンパイラによるアライメントの問題です。 勝手にこうされると困ることもあるので、 明示的にアライメントを1バイト単位にする事で、 この様なことを防ぐことが出来ます。 以下に紹介する例はVC6で確認しています。 #include <iostream.h> struct {  int a;  int b;  int c; } oshiete1; struct {  int a;  short b;  int c; } oshiete2; #pragma pack(push,1) struct {  int a;  short b;  int c; } oshiete3; #pragma pack(pop) int main( void ) {  cout << "oshiete1(b is int)" << endl;  cout << &oshiete1.a << endl;  cout << &oshiete1.b << endl;  cout << &oshiete1.c << endl;  cout << "oshiete2(b is short and non pack)" << endl;  cout << &oshiete2.a << endl;  cout << &oshiete2.b << endl;  cout << &oshiete2.c << endl;  cout << "oshiete3(b is short and pack 1)" << endl;  cout << &oshiete3.a << endl;  cout << &oshiete3.b << endl;  cout << &oshiete3.c << endl;  return 0; } ただし、pragmaの動作は環境に依存するので、 お使いのコンパイラにはこの機能が無いものも 存在します。

  • asuncion
  • ベストアンサー率33% (2127/6289)
回答No.3

> 構造体の中で宣言された変数の領域は連続した場所を確保する 必ずしも、そうなりません。 今回経験なさったように、構造体のメンバーどうしの間に すきま(パディングといいます)が入ることは、 ごく普通にあります。

noname#96023
noname#96023
回答No.2

昔勉強した知識程度ですが OSがメモリにアクセスする時はワード単位でアクセスします。 32bitOSなら一般に4バイトで1ワードです で、変数bをshort型にしてメモリアドレスを詰めると、必然的に変数cはワードをまたぐことになります。 その結果、変数cにアクセスするには2ワード読み出す必要が出てしまいます。 コンパイラの最適化オプションを外せばアドレスが詰まって確保される気もしますがね。。。

  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.1

アライメントの指定をしていないからですよ C++のマニュアルで アライメントとか #pragma packなどについて調べてみましょう 80386以降のx86CPUの場合4の倍数になっていないアドレスの参照は効率が低下します VC++の場合 構造体はいずれかのメンバーの最大のアライメントにそろえることになっていますのでWin32の場合 int short intなら 4バイト境界にそろえられることになります

関連するQ&A

専門家に質問してみよう