C言語のメモリ管理
変数と関数がメモリ上でどのように割り当てられているか実験
#include <stdio.h> #include <stdlib.h> int global; static int stglobal; void func (int p) { static int s; int local; printf("parameter addr : %p\n", &p); printf("function static addr : %p\n", &s); printf("func local addr : %p\n", &local); } int main(void) { char *alloc = malloc(1000); func(100); printf("allocated addr : %p\n", alloc); printf("global var addr : %p\n", &global); printf("static var addr : %p\n", &stglobal); printf("func () addr : %p\n", func); printf("main() addr : %p\n", main); printf("addr of printf : %p\n", printf); return 0; }
出力結果
parameter addr : 0x7fff68308afc
function static addr : 0x10870a078
func local addr : 0x7fff68308af8
allocated addr : 0x1088008f0
global var addr : 0x10870a080
static var addr : 0x10870a07c
func () addr : 0x108709ce0
main() addr : 0x108709d50
addr of printf : 0x7fff8b7f9222
このように配置されているはず
プログラム領域
func() addr : 0x108709ce0
main() addr : 0x108709d50
静的記憶領域
function static addr : 0x10870a078
static var addr : 0x10870a07c
global var addr : 0x10870a080
動的記憶領域(ヒープ)
allocated addr : 0x1088008f0
スタック
func local addr : 0x7fff68308af8
parameter addr : 0x7fff68308afc
printfのアドレスはプログラム領域になるはずだが、スタックのアドレスに近い場所になっている。
原因は不明。
バイトオーダー。基本データ型がメモリのどこに配置されているか調べる
prmem関数は指定アドレスから指定バイト数だけのメモリの内容を16進数で表示する
#include <stdio.h> #include <stdlib.h> void prmem (const void *_p, int n) { /* signed char(-128-127)ではなくunsigned char(0-255)と解釈させる */ const unsigned char *p = _p; char i, j; for (i=0; i<n; ++i, ++p) { printf("%02x", *p); } } int main(void) { char c = 0x12; short h = 0x1234; long l = 0x12345678; int i = 0x12345678; float f = 2.3; double g = 2.3; double fg; printf("char %p : %02x :", &c, c); prmem(&c, sizeof(c)); printf("\n"); printf("short %p : %02x :", &h, h); prmem(&h, sizeof(h)); printf("\n"); printf("long %p : %04x :", &l, l); prmem(&l, sizeof(l)); printf("\n"); printf("int %p : %04x :", &i, i); prmem(&i, sizeof(i)); printf("\n"); printf("float %p : %20.16f :", &f, f); prmem(&f, sizeof(f)); printf("\n"); printf("float %p : %20.16f :", &g, g); prmem(&g, sizeof(g)); printf("\n"); fg = f; printf("float %p : %20.16f :", &fg, fg); prmem(&fg, sizeof(fg)); printf("\n"); printf("double - float : %g\n", g - fg); return 0; }
出力結果
char 0x7fff6aa44b17 : 12 :12
short 0x7fff6aa44b14 : 1234 :3412
long 0x7fff6aa44b08 : 12345678 :78563412
int 0x7fff6aa44b04 : 12345678 :78563412
float 0x7fff6aa44b00 : 2.2999999523162842 :33331340
float 0x7fff6aa44af8 : 2.2999999999999998 :6666666666660240
float 0x7fff6aa44af0 : 2.2999999523162842 :0000006066660240
double - float : 4.76837e-08
使用したPCはx86系の為最下位バイトが最初のアドレスに、最上位バイトが最後のアドレスに記憶される
⇒1234だと34 12の順にメモリに配置される