低レベルなヒトの覚え書き

●LSI C-86のエラー

2. 「NULL pointer assignment」(と見せかけて、本当はスタックオーバーフロー)


[実験 - その4]

目的は、コンパイル時の条件や、自動変数の配列のサイズが異なることによって、メモリの使われ方にどのような変化が見られるのかを観察すること。
方法としては、リスト7のようなプログラムを使用して、変数や関数のアドレスを表示させてみました。

[リスト7]
 | #include<stdio.h>
 | #include<malloc.h>
 | int main() {
 |   static char A[2000];
 |   char B[2000];
 |   char *C;
 |   C=malloc(2000);
 |   printf("D_Static:%05d\nD_Auto__:%05d\nD_Heap__:%05d\n"
 |     "F_main__:%05d\nF_malloc:%05d\nF_printf:%05d\nF_free__:%05d\n",
 |     &A, &B, C, main, malloc, printf, free);
 |   free(C);
 |   return 0;
 | }
◆結果: 配列B(自動変数)のサイズを2000とした場合
[表5]
 -----------------------------------------------------------------------------------------
  コンパイル条件                            メモリ上の並び
 -----------------------------------------------------------------------------------------
   (ノーマル)           main,       Stat, mall, free, prin,                   Auto, Heap
                        0735,       1128, 1804, 1976, 2091,                   3994, 6150
   -h                   main,       Stat, mall, free, prin,                   Auto, Heap
                        0735,       1148, 1832, 2004, 2119,                   4026, 6182
   -lintlib       Stat, main, prin,                         mall,       free, Auto, Heap
                  0620, 0735, 0814,                         3188,       3360, 3498, 5654
   -h, -lintlib   Stat, main, prin,                         mall,       free, Auto, Heap
                  0640, 0735, 0817,                         3216,       3388, 3514, 5670
 -----------------------------------------------------------------------------------------
  # 全体を通じて、AutoとHeapの差は配列Bのサイズにほぼ一致。
  # 「-h」を指定した場合、main以外のアドレスが通常より30程度後方へ移動。
  # intlibをリンクした場合、main以外の位置が大きく変化(特にprintf)。
  # 「-h」とintlibを同時に使用した場合、両方の影響が単純に重なる。
◆結果: 配列Bのサイズを2300とした場合
[表6]
 -----------------------------------------------------------------------------------------
  コンパイル条件                            メモリ上の並び
 -----------------------------------------------------------------------------------------
   (ノーマル)           main,       Stat, mall, free, prin,                   Auto, Heap
                        0735,       1128, 1804, 1976, 2091,                   3694, 6150
   -h                   main,       Stat, mall, free, prin,                   Auto, Heap
                        0735,       1148, 1832, 2004, 2119,                   3726, 6182
   -lintlib       Stat, main, prin,                         mall, Auto, free,       Heap
                  0620, 0735, 0814,                         3188, 3198, 3360,       5654
   -h, -lintlib   Stat, main, prin,                         mall, Auto, free,       Heap
                  0640, 0735, 0817,                         3214, 3216, 3388,       5670
 -----------------------------------------------------------------------------------------
  # 配列Bのサイズが増えた分、Autoが300前方へ(スタックは後方から使用される)。
  # Autoの範囲がfree関数と重複しているのに、なぜかエラーになっていない。
◆結果: 配列Bのサイズを2400とした場合
[表7]
 -----------------------------------------------------------------------------------------
  コンパイル条件                            メモリ上の並び
 -----------------------------------------------------------------------------------------
   -lintlib       Stat, main, prin,                   Auto, mall,       free,       Heap
                  0620, 0735, 0814,                   3098, 3188,       3360,       5642
   -h, -lintlib   Stat, main, prin,                   Auto, mall,       free,       Heap
                  0620, 0735, 0817,                   3114, 3216,       3388,       5658
 -----------------------------------------------------------------------------------------
  # ノーマル条件では何も表示しないままフリーズ。
  # 「-h」条件では「Division by 0」を表示してフリーズ。
  # intlibをリンクした2つの条件では、結果の表示後にフリーズ。
  # 配列Bのサイズが増えた分、Autoがさらに前方へ。
◆結果: 配列Bのサイズを2400として、スタックを3000確保した場合
[表8]
 -----------------------------------------------------------------------------------------
  コンパイル条件                            メモリ上の並び
 -----------------------------------------------------------------------------------------
   (ノーマル)          main,       Stat, mall, free, prin,                    Auto, Heap
                       0735,       1128, 1804, 1976, 2091,                    4194, 6650
   -h                  main,       Stat, mall, free, prin,                    Auto, Heap
                       0735,       1148, 1832, 2004, 2119,                    4226, 6682
   -lintlib      Stat, main, prin,                         mall, free,        Auto, Heap
                 0620, 0735, 0814,                         3188, 3360,        3698, 6154
   -h -lintlib   Stat, main, prin,                         mall, free,        Auto, Heap
                 0640, 0735, 0817,                         3216, 3388,        3714, 6170
 -----------------------------------------------------------------------------------------
  # 配列Bの増分がスタックの増分で相殺されている。

→トップ , →ひとつ上(lsic2)


R.2: 2006/08/01
Copyright (C) 2005,2006 A.Satoshi