プログラミング言語論0525

プログラミング言語論
第七回
理工学部
情報システム工学科
新田直也
記憶クラス

メモリ管理は古くて新しい問題




使えるメモリは有限.
メモリの使い方は実行速度にも影響.
さまざまな環境: 携帯電話,デジタル家電…
「忘れてもいいことはさっさと忘れる」が基本.


長く覚えておくための記憶領域: ヒープ領域
一時的に覚えておくための記憶領域: スタック領域
プログラムのメモリマップ

各プログラムに割り当てられるメモリの領域は以下
のようになっている.
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番地