目的は、コンパイル時の条件や、自動変数の配列のサイズが異なることによって、メモリの使われ方にどのような変化が見られるのかを観察すること。
方法としては、リスト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; | }
[表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を同時に使用した場合、両方の影響が単純に重なる。
[表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関数と重複しているのに、なぜかエラーになっていない。
[表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がさらに前方へ。
[表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の増分がスタックの増分で相殺されている。