第88章 配列内のアドレスの走査

目次

88.1. スタックアロケーター(可変長のリクエストサイズに対応、難易度高いのでスキップ推奨)

 スタックアロケーターの解説を始める前に一つクリアにしときましょう。

 まずスタックは上位アドレスから下位アドレスに下方向に拡大していきます。

main.cpp. 

  1 #include <cstdio>
  2
  3 void bar(){
  4   int a,b,c,d,e;
  5   std::printf("a: %p\n",&a);
  6   std::printf("b: %p\n",&b);
  7   std::printf("c: %p\n",&c);
  8   std::printf("d: %p\n",&d);
  9   std::printf("e: %p\n",&e);
 10 }
 11
 12 void foo(){
 13   int a,b,c,d,e;
 14   std::printf("a: %p\n",&a);
 15   std::printf("b: %p\n",&b);
 16   std::printf("c: %p\n",&c);
 17   std::printf("d: %p\n",&d);
 18   std::printf("e: %p\n",&e);
 19   std::printf("=== bar ===\n");
 20   bar();
 21 }
 22
 23 int main(){
 24   int a,b,c,d,e;
 25   std::printf("a: %p\n",&a);
 26   std::printf("b: %p\n",&b);
 27   std::printf("c: %p\n",&c);
 28   std::printf("d: %p\n",&d);
 29   std::printf("e: %p\n",&e);
 30   std::printf("=== foo ===\n");
 31   foo();
 32   return 0;
 33 }

ビルドと実行結果. 

$ g++ main.cpp
$ ./a.out
a: 0x7fffd7fa7464
b: 0x7fffd7fa7468
c: 0x7fffd7fa746c
d: 0x7fffd7fa7470
e: 0x7fffd7fa7474
=== foo ===
a: 0x7fffd7fa7434
b: 0x7fffd7fa7438
c: 0x7fffd7fa743c
d: 0x7fffd7fa7440
e: 0x7fffd7fa7444
=== bar ===
a: 0x7fffd7fa7404
b: 0x7fffd7fa7408
c: 0x7fffd7fa740c
d: 0x7fffd7fa7410
e: 0x7fffd7fa7414

 このコードを見ると関数内で宣言順で変数のアドレスをチェックすると 4 バイト間隔となっています。

 しかし関数をコールすると、アドレスは下方向にシフトします。

 例えば main 関数の a は 0x7fffd7fa7464 ですが foo 関数の a は 0x7fffd7fa7434 というように値が減少しています。

 まあこんな感じで変数の宣言順というのはわかったのですが、アロケーターにとっては配列型のアドレス構造の方を知りたいです。

 では配列内のアドレスはどうなのか確かめて見ましょう。

main.cpp. 

  1 #include <cstdio>
  2
  3 int main()
  4 {
  5   int x[10];
  6
  7   for(int i = 0; i < 10; ++i)
  8   {
  9     std::printf("%p\n",x+i);
 10   }
 11
 12   return 0;
 13 }

ビルドと実行結果. 

$ g++ main.cpp
$ ./a.out
0x7ffca911c040
0x7ffca911c044
0x7ffca911c048
0x7ffca911c04c
0x7ffca911c050
0x7ffca911c054
0x7ffca911c058
0x7ffca911c05c
0x7ffca911c060
0x7ffca911c064

これは文句なく上方向に動いていますね。

0x7ffca911c040 から 0x7ffca911c064 だと一目瞭然です。

つまりスタックにおいては、一旦宣言・定義した配列・変数のアドレスは減算でなく加算されるってことです。

Copyright 2018-2019, by Masaki Komatsu