• 検索結果がありません。

アルゴリズムとデータ構造 補足資料 11-1 「 malloc と free 」

N/A
N/A
Protected

Academic year: 2021

シェア "アルゴリズムとデータ構造 補足資料 11-1 「 malloc と free 」"

Copied!
26
0
0

読み込み中.... (全文を見る)

全文

(1)

「 malloc と free 」

横浜国立大学 理工学部 数物・電子情報系学科 富井尚志

(2)

Random Access Memory (RAM)

「アドレス」と「中身」

有限個のセル(資源)

CPUは、メモリに対して次の操作を行う

アドレスを指定して、その内容を読み出す(load)

アドレスを指定して、その内容を書き込む(store)

CPUの演算と比べれば、読み書きには「それなりに」時間がかかる

e.g. メモリバスの周波数は、CPUの内部周波数の1/10程度

アドレスの指定は「任意」

どのアドレスを指定しても、読み書きが可能

Random Access Memory と呼ばれる

2次記憶と比べれば、「そこそこ速く」読み書きが可能

c.f. Sequential Access Device

(ディスクやテープ;ディスクはアドレス指定が可能だが、「極めて遅い」)

メモリの中身の種類

データ

アドレス

(3)

0x 40ea 0800 1101 0000

0x 40ea 0801 0000 0111

0x 40ea 0802 0100 1011

0x 40ea 0803 1011 1111

0x 40ea 0804 0000 0000

0x 40ea 0805 0000 0000

0x 40ea 0806 0000 0000

0x 40ea 0807 0001 0100

0x 40ea 0808 0100 0001

0x 40ea 0809 1011 0111

0x 40ea 080a 0100 0001

0x 40ea 080b 1101 0000

0x 40ea 080c 0100 1100

0x 40ea 080d 0110 1111

0x 40ea 080e 1010 0111

0x 40ea 080f 0101 0000

0x 40ea 0810 1101 0000

a = 20;

printf(“a:%x = %d\n”, &a, a);

return 0;

}

00000000 00000000 00000000 00010100

a

int 型( 32bit ) この場合の a は?

→ int 型( 32bit の箱)の変数 a は、

中身が 20 ( 2 進数では 10100 )

実行すると、以下の結果が出た。

a: 40ea0804 = 20

a は、物理的にどこに存在する?

→ 記憶(メモリ)の中

(OSに割り当ててもらう; 毎回変

わる)

a は、具体的にどこ?

→ 今回は 0x 40ea 0804 番地からの 4 バイ ト分→ ( のアドレス)

&a a

(4)

0x 40ea 0800 0x d007 4bbf

0x 40ea 0804 0x 0000 0014

0x 40ea 0808 0x 41b7 41b0

0x 40ea 080c 0x 4c6f a750

0x 40ea 0810 0x 0000 0000

0x 40ea 0814 0x 0000 0000

0x 40ea 0818 0x 0000 0000

0x 40ea 081c 0x ef5c 2100

0x 40ea 0820 0x 0100 0001

0x 40ea 0824 0x 1011 0111

0x 40ea 0828 0x 0100 0001

0x 40ea 082c 0x 1101 0000

0x 40ea 0830 0x 0100 1100

0x 40ea 0834 0x 0110 1111

0x 40ea 0838 0x 1010 0111

0x 40ea 083c 0x 0101 0000

&a a

00000000 00000000 00000000 00010100

a

int 型( 32bit )

→ int 型( 32bit の箱)の変数

a は、

中身が 20 ( 16 進数では

14 )

変数 a のアドレスは

、 0x 40ea0804 番 地

(5)

0x 40ea 0800 0x d007 4bbf

0x 40ea 0804 0x 0000 0014

0x 40ea 0808 0x 41b7 41b0

0x 40ea 080c 0x 4c6f a750

0x 40ea 0810 0x 0000 0000

0x 40ea 0814 0x 0000 0000

0x 40ea 0818 0x 0000 0000

0x 40ea 081c 0x ef5c 2100

0x 40ea 0820 0x 0100 0001

0x 40ea 0824 0x 1011 0111

0x 40ea 0828 0x 0100 0001

0x 40ea 082c 0x 1101 0000

0x 40ea 0830 0x 0100 1100

0x 40ea 0834 0x 0110 1111

0x 40ea 0838 0x 1010 0111

0x 40ea 083c 0x 0101 0000

int main(void) {

struct list a, *p;

a.key = 20;

a.next = NULL;

p = &a;

printf(“a:%0x = [%d, %0x]\n”, p, a.key, a.next);

return 0;

}

変数によるプログラム:

プログラム中では、

変数の枠は動かない

(6)

0x 40ea 0800 0x d007 4bbf

0x 40ea 0804 0x 0000 0014

0x 40ea 0808 0x 41b7 41b0

0x 40ea 080c 0x 4c6f a750

0x 40ea 0810 0x 0000 0000

0x 40ea 0814 0x 0000 0000

0x 40ea 0818 0x 0000 0000

0x 40ea 081c 0x ef5c 2100

0x 40ea 0820 0x 0100 0001

0x 40ea 0824 0x 1011 0111

0x 40ea 0828 0x 0100 0001

0x 40ea 082c 0x 1101 0000

0x 40ea 0830 0x 0100 1100

0x 40ea 0834 0x 0110 1111

0x 40ea 0838 0x 1010 0111

0x 40ea 083c 0x 0101 0000

int main(void) {

struct list a, *p;

a.key = 20;

a.next = NULL;

p = &a;

printf(“a:%0x = [%d, %0x]\n”, p, a.key, a.next);

return 0;

}

a.next

p

変数によるプログラム:

プログラム中では、

変数の枠は動かない

(7)

0x 40ea 0800 20

0x 40ea 0804 0x 0000 0014

0x 40ea 0808 0x 41b7 41b0

0x 40ea 080c 0x 4c6f a750

0x 40ea 0810 0x 0000 0000

0x 40ea 0814 0x 0000 0000

0x 40ea 0818 0x 0000 0000

0x 40ea 081c 0x ef5c 2100

0x 40ea 0820 0x 0100 0001

0x 40ea 0824 0x 1011 0111

0x 40ea 0828 0x 0100 0001

0x 40ea 082c 0x 1101 0000

0x 40ea 0830 0x 0100 1100

0x 40ea 0834 0x 0110 1111

0x 40ea 0838 0x 1010 0111

0x 40ea 083c 0x 0101 0000

int main(void) {

struct list a, *p;

a.key = 20;

a.next = NULL;

p = &a;

printf(“a:%0x = [%d, %0x]\n”, p, a.key, a.next);

return 0;

} a a.key

a.next

&a

p

(8)

0x 40ea 0800 20

0x 40ea 0804 0x 0000 0000

0x 40ea 0808 0x 41b7 41b0

0x 40ea 080c 0x 4c6f a750

0x 40ea 0810 0x 0000 0000

0x 40ea 0814 0x 0000 0000

0x 40ea 0818 0x 0000 0000

0x 40ea 081c 0x ef5c 2100

0x 40ea 0820 0x 0100 0001

0x 40ea 0824 0x 1011 0111

0x 40ea 0828 0x 0100 0001

0x 40ea 082c 0x 1101 0000

0x 40ea 0830 0x 0100 1100

0x 40ea 0834 0x 0110 1111

0x 40ea 0838 0x 1010 0111

0x 40ea 083c 0x 0101 0000

int main(void) {

struct list a, *p;

a.key = 20;

a.next = NULL;

p = &a;

printf(“a:%0x = [%d, %0x]\n”, p, a.key, a.next);

return 0;

}

a.next

p

(9)

0x 40ea 0800 20

0x 40ea 0804 0x 0000 0000

0x 40ea 0808 0x 41b7 41b0

0x 40ea 080c 0x 4c6f a750

0x 40ea 0810 0x 40ea 0800

0x 40ea 0814 0x 0000 0000

0x 40ea 0818 0x 0000 0000

0x 40ea 081c 0x ef5c 2100

0x 40ea 0820 0x 0100 0001

0x 40ea 0824 0x 1011 0111

0x 40ea 0828 0x 0100 0001

0x 40ea 082c 0x 1101 0000

0x 40ea 0830 0x 0100 1100

0x 40ea 0834 0x 0110 1111

0x 40ea 0838 0x 1010 0111

0x 40ea 083c 0x 0101 0000

int main(void) {

struct list a, *p;

a.key = 20;

a.next = NULL;

p = &a;

printf(“a:%0x = [%d, %0x]\n”, p, a.key, a.next);

return 0;

} a a.key

a.next

&a

p

(10)

0x 40ea 0800 20

0x 40ea 0804 0x 0000 0000

0x 40ea 0808 0x 41b7 41b0

0x 40ea 080c 0x 4c6f a750

0x 40ea 0810 0x 40ea 0800

0x 40ea 0814 0x 0000 0000

0x 40ea 0818 0x 0000 0000

0x 40ea 081c 0x ef5c 2100

0x 40ea 0820 0x 0100 0001

0x 40ea 0824 0x 1011 0111

0x 40ea 0828 0x 0100 0001

0x 40ea 082c 0x 1101 0000

0x 40ea 0830 0x 0100 1100

0x 40ea 0834 0x 0110 1111

0x 40ea 0838 0x 1010 0111

0x 40ea 083c 0x 0101 0000

int main(void) {

struct list a, *p;

a.key = 20;

a.next = NULL;

p = &a;

printf(“a:%0x = [%d, %x]\n”, p, a.key, a.next);

return 0;

}

a.next

p

a: 40ea0800 = [20, 0]

と表示

(11)

0x 40ea 0800 0x 0000 0014

0x 40ea 0804 0x 0000 0000

0x 40ea 0808 0x 41b7 41b0

0x 40ea 080c 0x 4c6f a750

0x 40ea 0810 0x 40ea 0800

0x 40ea 0814 0x 0000 0000

0x 40ea 0818 0x 0000 0000

0x 40ea 081c 0x ef5c 2100

0x 40ea 0820 0x 0100 0001

0x 40ea 0824 0x 1011 0111

0x 40ea 0828 0x 0100 0001

0x 40ea 082c 0x 1101 0000

0x 40ea 0830 0x 0100 1100

0x 40ea 0834 0x 0110 1111

0x 40ea 0838 0x 1010 0111

0x 40ea 083c 0x 0101 0000

int main(void) {

struct list *p;

p = (struct list *)malloc(sizeof(struct list));

p->key = 21;

p->next = NULL;

printf(“p->%x = [%d, %x]\n”, p, p->key, p->next);

return 0;

}

動的領域割当によるプログラム:

プログラム中で、

領域を確保する

(枠が増える・減る)

(12)

0x 40ea 0800 0x 0000 0014

0x 40ea 0804 0x 0000 0000

0x 40ea 0808 0x 41b7 41b0

0x 40ea 080c 0x 4c6f a750

0x 40ea 0810 0x 40ea 0800

0x 40ea 0814 0x 0000 0000

0x 40ea 0818 0x 0000 0000

0x 40ea 081c 0x ef5c 2100

0x 40ea 0820 0x 0100 0001

0x 40ea 0824 0x 1011 0111

0x 40ea 0828 0x 0100 0001

0x 40ea 082c 0x 1101 0000

0x 40ea 0830 0x 0100 1100

0x 40ea 0834 0x 0110 1111

0x 40ea 0838 0x 1010 0111

0x 40ea 083c 0x 0101 0000

int main(void) {

struct list *p;

p = (struct list *)malloc(sizeof(struct list));

p->key = 21;

p->next = NULL;

printf(“p->%x = [%d, %x]\n”, p, p->key, p->next);

return 0;

} p

p は変数

動的領域割当によるプログラム:

プログラム中で、

領域を確保する

(13)

0x 40ea 0800 0x 0000 0014

0x 40ea 0804 0x 0000 0000

0x 40ea 0808 0x 41b7 41b0

0x 40ea 080c 0x 4c6f a750

0x 40ea 0810 0x 40ea 0800

0x 40ea 0814 0x 0000 0000

0x 40ea 0818 0x 0000 0000

0x 40ea 081c 0x 40ea 082c

0x 40ea 0820 0x 0100 0001

0x 40ea 0824 0x 1011 0111

0x 40ea 0828 0x 0100 0001

0x 40ea 082c 0x 1101 0000

0x 40ea 0830 0x 0100 1100

0x 40ea 0834 0x 0110 1111

0x 40ea 0838 0x 1010 0111

0x 40ea 083c 0x 0101 0000

int main(void) {

struct list *p;

p = (struct list *)malloc(sizeof(struct list));

p->key = 21;

p->next = NULL;

printf(“p->%x = [%d, %x]\n”, p, p->key, p->next);

return 0;

} p

key next

領域を割当てる アドレスを 代入

動的領域割当によるプログラム:

プログラム中で、

領域を確保する

(枠が増える・減る)

(14)

0x 40ea 0800 0x 0000 0014

0x 40ea 0804 0x 0000 0000

0x 40ea 0808 0x 41b7 41b0

0x 40ea 080c 0x 4c6f a750

0x 40ea 0810 0x 40ea 0800

0x 40ea 0814 0x 0000 0000

0x 40ea 0818 0x 0000 0000

0x 40ea 081c 0x 40ea 082c

0x 40ea 0820 0x 0100 0001

0x 40ea 0824 0x 1011 0111

0x 40ea 0828 0x 0100 0001

0x 40ea 082c 0x 1101 0000

0x 40ea 0830 0x 0100 1100

0x 40ea 0834 0x 0110 1111

0x 40ea 0838 0x 1010 0111

0x 40ea 083c 0x 0101 0000

int main(void) {

struct list *p;

p = (struct list *)malloc(sizeof(struct list));

p->key = 21;

p->next = NULL;

printf(“p->%x = [%d, %x]\n”, p, p->key, p->next);

return 0;

} p

key next

領域を割当てる アドレスを 代入

動的領域割当によるプログラム:

プログラム中で、

領域を確保する

(15)

0x 40ea 0800 0x 0000 0014

0x 40ea 0804 0x 0000 0000

0x 40ea 0808 0x 41b7 41b0

0x 40ea 080c 0x 4c6f a750

0x 40ea 0810 0x 40ea 0800

0x 40ea 0814 0x 0000 0000

0x 40ea 0818 0x 0000 0000

0x 40ea 081c 0x 40ea 082c

0x 40ea 0820 0x 0100 0001

0x 40ea 0824 0x 1011 0111

0x 40ea 0828 0x 0100 0001

0x 40ea 082c 21

0x 40ea 0830 0x 0100 1100

0x 40ea 0834 0x 0110 1111

0x 40ea 0838 0x 1010 0111

0x 40ea 083c 0x 0101 0000

int main(void) {

struct list *p;

p = (struct list *)malloc(sizeof(struct list));

p->key = 21;

p->next = NULL;

printf(“p->%x = [%d, %x]\n”, p, p->key, p->next);

return 0;

} p

key next

参照先に代入

動的領域割当によるプログラム:

プログラム中で、

領域を確保する

(枠が増える・減る)

(16)

0x 40ea 0800 0x 0000 0014

0x 40ea 0804 0x 0000 0000

0x 40ea 0808 0x 41b7 41b0

0x 40ea 080c 0x 4c6f a750

0x 40ea 0810 0x 40ea 0800

0x 40ea 0814 0x 0000 0000

0x 40ea 0818 0x 0000 0000

0x 40ea 081c 0x 40ea 082c

0x 40ea 0820 0x 0100 0001

0x 40ea 0824 0x 1011 0111

0x 40ea 0828 0x 0100 0001

0x 40ea 082c 21

0x 40ea 0830 0x 0000 0000

0x 40ea 0834 0x 0110 1111

0x 40ea 0838 0x 1010 0111

0x 40ea 083c 0x 0101 0000

int main(void) {

struct list *p;

p = (struct list *)malloc(sizeof(struct list));

p->key = 21;

p->next = NULL;

printf(“p->%x = [%d, %x]\n”, p, p->key, p->next);

return 0;

} p

key next

参照先に代入

動的領域割当によるプログラム:

プログラム中で、

領域を確保する

(17)

0x 40ea 0800 0x 0000 0014

0x 40ea 0804 0x 0000 0000

0x 40ea 0808 0x 41b7 41b0

0x 40ea 080c 0x 4c6f a750

0x 40ea 0810 0x 40ea 0800

0x 40ea 0814 0x 0000 0000

0x 40ea 0818 0x 0000 0000

0x 40ea 081c 0x 40ea 082c

0x 40ea 0820 0x 0100 0001

0x 40ea 0824 0x 1011 0111

0x 40ea 0828 0x 0100 0001

0x 40ea 082c 21

0x 40ea 0830 0x 0000 0000

0x 40ea 0834 0x 0110 1111

0x 40ea 0838 0x 1010 0111

0x 40ea 083c 0x 0101 0000

int main(void) {

struct list *p;

p = (struct list *)malloc(sizeof(struct list));

p->key = 21;

p->next = NULL;

printf(“p->%x = [%d, %x]\n”, p, p->key, p->next);

return 0;

} p

key next

参照先に代入 p-> 40ea082c = [21, 0]

と表示

(18)

int main(void) {

struct list *p;

p = (struct list *)malloc(sizeof(struct list));

p->key = 21;

p->next = NULL;

printf(“p->%x = [%d, %x]\n”, p, p->key, p->next);

return 0;

} p

21 NULL

key next

p-> 40ea082c = [21, 0]

と表示

(19)

p

21 NULL

key next

2.その量は、” struct list” 型 1 個分

3. malloc の戻り値は、割当てたメモリの先頭アドレス

4.そのアドレス(参照先)の中身は “ struct list” 型として、「キャスト」(型変換)

5.“ struct list” 型へのポインタとして、アドレスを代入

要するに、

新しく「箱」ができる。

この箱に名前(変数名)はない。

だから、ポインタ変数 p で指し示しておく必要がある。

この書き方は、憶えましょう。

結果は

←これ

(20)

p

この名前のない「箱」の領域は、

開放する(使わなかったことにする)ことができる。

赤い箱は解放された。

つまり、このメモリは、別のプログラムや別の機会に使われる。

でも、ポインタ変数 p にアドレスだけは残っている。

うっかり p の参照先に代入しようとすると、 OS が怒る。( Segmentation Fault )

この使い方も憶えましょう。

結果は

←これ

(21)

0x 40ea 0800 20

0x 40ea 0804 0x 0000 0000

0x 40ea 0808 0x 41b7 41b0

0x 40ea 080c 0x 4c6f a750

0x 40ea 0810 0x 40ea 0800

0x 40ea 0814 0x 0000 0000

0x 40ea 0818 0x 0000 0000

0x 40ea 081c 0x 40ea 082c

0x 40ea 0820 0x 0100 0001

0x 40ea 0824 0x 1011 0111

0x 40ea 0828 0x 0100 0001

0x 40ea 082c 21

0x 40ea 0830 0x 0000 0000

0x 40ea 0834 0x 0110 1111

0x 40ea 0838 0x 1010 0111

0x 40ea 083c 0x 0101 0000

int main(void) {

struct list a, *p;

a.key = 20;

a.next = NULL;

p = (struct list *)malloc(sizeof(struct list));

p->key = 21;

p->next = NULL;

printf(“a:%0x = [%d, %0x]\n”, &a, a.key, a.next);

printf(“p->%x = [%d, %x]\n”, p, p->key, p->next);

free(p);

return 0;

} p

key next

a a.key

a.next

(22)

int main(void) {

struct list a, *p;

a.key = 20;

a.next = NULL;

p = (struct list *)malloc(sizeof(struct list));

p->key = 21;

p->next = NULL;

printf(“a:%0x = [%d, %0x]\n”, &a, a.key, a.next);

printf(“p->%x = [%d, %x]\n”, p, p->key, p->next);

free(p);

return 0;

p

21 NULL

key next

NULL

a.next

(23)

p

21 NULL

key next

NULL

a.next

変数:

・・変数領域

malloc によって確保された領域:

・動的割当領域

(24)

p

21 NULL

key next

変数:

・ブロック内で「宣言」されると、

そのブロックの中でずっと有効 (スコープ)

・・変数領域

malloc によって確保された領域:

・プログラムの実行中に「割当て」。

または、「解放」。

(必要時に割り当てて、

不要になったら解放する。)

・動的割当領域

(25)

p

21 NULL

key next

NULL

a.next

変数:

・ブロック内で「宣言」されると、

そのブロックの中でずっと有効 (スコープ)

・名前(変数名)がある。

・変数領域

malloc によって確保された領域:

・プログラムの実行中に「割当て」。

または、「解放」。

(必要時に割り当てて、

不要になったら解放する。)

・名前はない。

だから、アドレスを記録しなくては ならない。

・動的割当領域

(26)

メモリ(記憶領域)は有限な資源。

使わないのにずっと確保される「静的領域」は資源の無駄。もったいない (MOTTAINAI) p

21 NULL

key next

変数:

・ブロック内で「宣言」されると、

そのブロックの中でずっと有効 (スコープ)

・名前(変数名)がある。

・変数領域

malloc によって確保された領域:

・プログラムの実行中に「割当て」。

または、「解放」。

(必要時に割り当てて、

不要になったら解放する。)

・名前はない。

だから、アドレスを記録しなくては ならない。

・動的割当領域

参照

関連したドキュメント

RCIC 室内の発熱と RCIC 室部屋の放熱・吸熱の熱バランスから、換気空調系停止後の RCIC 室の最高温度は約 54℃(補足資料

 事業アプローチは,貸借対照表の借方に着目し,投下資本とは総資産額

と発話行為(バロール)の関係が,社会構造(システム)とその実践(行

(1) 汚水の地下浸透を防止するため、 床面を鉄筋コンクリ-トで築 造することその他これと同等以上の効果を有する措置が講じら

マニピュレータで、プール 内のがれきの撤去や燃料取 り出しをサポートする テンシルトラスには,2本 のマニピュレータが設置さ

マニピュレータで、プール 内のがれきの撤去や燃料取 り出しをサポートする テンシルトラスには,2本 のマニピュレータが設置さ

1ヵ国(A国)で生産・製造が完結している ように見えるが、材料の材料・・・と遡って

添付資料 1.0.6 重大事故等対応に係る手順書の構成と概要について 添付資料 1.0.7 有効性評価における重大事故対応時の手順について 添付資料