プログラミング言語論 第七回 理工学部 情報システム工学科 新田直也 記憶クラス メモリ管理は古くて新しい問題 使えるメモリは有限. メモリの使い方は実行速度にも影響. さまざまな環境: 携帯電話,デジタル家電… 「忘れてもいいことはさっさと忘れる」が基本. 長く覚えておくための記憶領域: ヒープ領域 一時的に覚えておくための記憶領域: スタック領域 プログラムのメモリマップ 各プログラムに割り当てられるメモリの領域は以下 のようになっている. 0xffff番地 スタック領域 領域が増減する 1プログラムに 割り当てられる 領域 ヒープ領域 静的領域 書き換え不可能 プログラム領域 0x0000番地 各領域の説明 プログラム領域: プログラムの実行コード(機械語)が格納される. 静的領域: プログラムが持つ定数などが格納される. char *a = “This is a string.”; printf(“Hello World!!”); ヒープ領域: 大域変数(後で説明)が格納される. スタック領域: 自動変数(後で説明),関数の引数,戻り番地などが格納される. 自動変数 自動変数: 関数呼出し,ブロック開始時に生成される. 関数からの復帰,ブロック終了時に消滅する. スタック領域上に確保される. main () { int i, j; func(); } mainの中でのみ使用可能 mainを抜けると消滅 func() { int x, y; } funcの中でのみ使用可能 funcを抜けると消滅 静的変数 静的変数: 自動変数と同様,宣言した関数内でしか見れない. 関数からの復帰時に消滅せず値が保持される. ヒープ領域に確保される. main () { int i, j; tick(); tick(); } 静的変数であることを示す記憶指定子 tick() { static int count = 0; count++; } funcの中でのみ使用可能 次回呼出し時に値が残っている 大域変数 大域変数(外部変数): 関数の外で宣言する. 複数の関数で値を共有できる. プログラム実行中消滅しない. ヒープ領域に確保される. int i, j; mainでもfuncでも使用可能 消滅しない main () { i = 1; j = 2; func(); } func() { printf(“[%d,%d]”, i, j); } [1,2]が表示される 変数のスコープと寿命 スコープ: その変数を見れる範囲 寿命: その変数に値が保持されている期間 スコープ 寿命 自動変数 関数内 関数呼出しの間 静的変数 関数内 プログラムの全実行 大域変数 プログラム全体 プログラムの全実行 スコープと可視性 別々のスコープで同じ名前を使用できる. 名前が衝突したときは,内側のスコープを優先. int i, j; main内における i ,j main () { func1(); func2(); } func1() { int i, j; } func1内における i ,j func2() { int i, j; } func2内における i ,j スタック領域の詳細 関数呼出しに応じて スタック領域が確保される. main () { int x = 1; x = input(x); } int input(int y) { char s[10]; scanf(“%s”, s); printf("%s\n", s); return y + 1; } 0xffff番地 main用 x : y 戻り番地 : s[1] s[0] 引数用 20バイト input用 自動変数用 28バイト 0x0000番地 バッファオーバーフロー攻撃 scanfなどで戻り番地を上書きする. 戻り番地は29~32文字目 main () { int x = 1; x = input(x); } int input(int y) { char s[10]; scanf(“%s”, s); printf("%s\n", s); return y + 1; } 0xffff番地 main用 x : y 戻り番地 : 不正な s[1] コード s[0] 引数用 20バイト input用 自動変数用 28バイト 0x0000番地
© Copyright 2024 ExpyDoc