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

Slides:



Advertisements
Similar presentations
アルゴリズムとプログラミン グ (Algorithms and Programming) 第6回:クラスとインスタンス クラスの宣言 アクセス修飾子 インスタンスの生成 (new キーワード) this キーワード フィールドとメソッドの実際の定義と使い 方 クラスの宣言 アクセス修飾子 インスタンスの生成.
Advertisements

1 データ構造とアルゴリズム 第 3 回 配列,構造体,ポインタ ~ データ構造について学ぶための基礎~
メモリとポインタ. プログラムの前提 コンピュータは、0と1で計算をし、 0と1でデータを保存している。 メモリを学ぶのに必要な知識である。
アルゴリズムと データ構造 第 3 回 基本的なデータ構造(2) : 配列 1. 前回の復習 アルゴリズムの計算量 最悪(最大)計算量 計算量の漸近的評価 (オーダ)  多項式時間アルゴリズム( polynomial time algorithm )  指数時間アルゴリズム( exponential.
第6章 ポインタ ポインタが分からずにC言語を投げ出す人が数多くいます。 その半面、使いこなせば強力な武器となります。 しっかりと学習していきましょう C 言語 最難関文法 C 言語 最難関文法 1 第 6 章 ポインタ.
記 憶 管 理(1) オペレーティングシステム 第9回.
情報基礎演習B 後半第5回 担当 岩村 TA 谷本君.
プログラミング入門2 第10回 動的な領域確保 情報工学科 篠埜 功.
情報塾( ) CPUとメモリがどんなふうに動くのだろう。 レジスタやI/O プログラムの実行、マシン語。
データ構造とアルゴリズム 第10回 mallocとfree
アルゴリズムとプログラミング (Algorithms and Programming)
プログラミング言語Ⅰ(実習を含む。), 計算機言語Ⅰ・計算機言語演習Ⅰ, 情報処理言語Ⅰ(実習を含む。)
アルゴリズムとデータ構造 補足資料13-4 「2分探索木の追加・削除(ダイジェスト)」
12: コマンドライン引数 C プログラミング入門 総機1 (月1) Linux にログインし、以下の講義ページ を開いておくこと
第8回 プログラミングⅡ 第8回
アルゴリズムとデータ構造 補足資料7-3 「単純選択ソートselsort.c」
データ構造とアルゴリズム 第4回 リスト ~ データ構造(1)~.
アルゴリズムとデータ構造 補足資料4-2 「線形探索」
アルゴリズムとデータ構造 補足資料6-3 「サンプルプログラムcat3.c」
第4回放送授業.
アルゴリズムとデータ構造 第2回 線形リスト(復習その2).
プログラミング演習Ⅰ 課題2 10進数と2進数 2回目.
データ構造と アルゴリズム 第四回 知能情報学部 新田直也.
第3回 配列,構造体,ポインタ ~ データ構造について学ぶための基礎~
プログラミング論 ファイル入出力
データ構造とアルゴリズム 第4回 リスト ~ データ構造(1)~.
精密工学科プログラミング基礎 第10回資料 (12/18実施)
プログラミング 4 記憶の割り付け.
2005年度 データ構造とアルゴリズム 第3回 「C言語の復習:再帰的データ構造」
アルゴリズムとデータ構造 補足資料5-2 「サンプルプログラムsetop.c」
メモリの準備 メモリには、その準備の方法で2種類ある。 静的変数: コンパイル時にすでにメモリのサイズがわかっているもの。 普通の変数宣言
プログラミング入門2 第11回 情報工学科 篠埜 功.
プログラミング入門2 第11回 情報工学科 篠埜 功.
第7回 プログラミングⅡ 第7回
プログラミング言語論 第五回 理工学部 情報システム工学科 新田直也.
アルゴリズムとデータ構造 補足資料4-1 「メモリと配列」
アルゴリズムとデータ構造 補足資料5-1 「メモリとポインタ」
アルゴリズムとデータ構造 補足資料6-2 「サンプルプログラムcat2.c」
P n ポインタの基礎 5 q m 5 7 int* p; int 型の変数を指すポインタ int* q; int 型の変数を指すポインタ int n=5, m=7; int 型の変数 int array[3]; int* pArray[3]; p = &n; ポインタにアドレスを代入しているのでOK.
データ構造と アルゴリズム 第五回 知能情報学部 新田直也.
配列変数とポインタ 静的確保と動的確保 ポインタ配列 2次元配列 時間計測 第1回レポートの課題
オブジェクト指向言語論 第六回 知能情報学部 新田直也.
プログラミング言語論 第六回 理工学部 情報システム工学科 新田直也.
精密工学科プログラミング基礎Ⅱ 第5回資料 今回の授業で習得してほしいこと: 構造体 (教科書 91 ページ)
データ構造とアルゴリズム 第11回 リスト構造(1)
11: 動的メモリ確保 C プログラミング入門 総機1 (月1) Linux にログインし、以下の講義ページ を開いておくこと
文字列へのポインタの配列 static char *lines[MAXLINES]; lines[0] NULL
ポインタとポインタを用いた関数定義.
プログラミング論 ポインタ
アルゴリズムとデータ構造1 2009年6月15日
11: 動的メモリ確保 C プログラミング入門 基幹7 (水5) Linux にログインし、以下の講義ページを開いておく こと
アルゴリズムとデータ構造 補足資料11-3 「線形リストのオペレータ」
第5回 プログラミングⅡ 第5回
オブジェクト指向言語論 第五回 知能情報学部 新田直也.
情報処理Ⅱ 2006年11月24日(金).
11: 動的メモリ確保 C プログラミング入門 基幹7 (水5) Linux にログインし、以下の講義ページ を開いておくこと
プログラミング論 構造体
アルゴリズムとデータ構造 補足資料7-1 「メモリでの『構造体の配列』」
コンパイラ 第12回 実行時環境 ― 変数と関数 ― 38号館4階N-411 内線5459
アルゴリズムとデータ構造 補足資料6-1 「サンプルプログラムcat1.c」
アルゴリズムとデータ構造 2010年6月17日
アルゴリズムとデータ構造 補足資料5-3 「サンプルプログラムstrcat.c」
11: 動的メモリ確保 C プログラミング入門 基幹2 (月4) Linux にログインし、以下の講義ページ を開いておくこと
2005年度 データ構造とアルゴリズム 第2回 「C言語の復習:配列」
プログラミング演習II 2004年11月 16日(第5回) 理学部数学科・木村巌.
プログラミング演習II 2003年12月10日(第7回) 木村巌.
TList リスト構造とは? 複数のデータを扱うために、 データの内容と、次のデータへのポインタを持つ構造体を使う。
プログラミング演習II 2003年10月29日(第2,3回) 木村巌.
オブジェクト指向言語論 第六回 知能情報学部 新田直也.
12: コマンドライン引数 C プログラミング入門 基幹2 (月4) Linux にログインし、以下の講義ページ を開いておくこと
Presentation transcript:

アルゴリズムとデータ構造 補足資料11-1 「mallocとfree」 横浜国立大学 理工学部 数物・電子情報系学科 富井尚志

メモリの「物理的」な構成 Random Access Memory (RAM) 「アドレス」と「中身」 有限個のセル(資源) CPUは、メモリに対して次の操作を行う アドレスを指定して、その内容を読み出す(load) アドレスを指定して、その内容を書き込む(store) CPUの演算と比べれば、読み書きには「それなりに」時間がかかる e.g. メモリバスの周波数は、CPUの内部周波数の1/10程度 アドレスの指定は「任意」 どのアドレスを指定しても、読み書きが可能 Random Access Memory と呼ばれる 2次記憶と比べれば、「そこそこ速く」読み書きが可能 c.f. Sequential Access Device (ディスクやテープ;ディスクはアドレス指定が可能だが、「極めて遅い」) メモリの中身の種類 データ アドレス プログラム(命令)

printf(“a:%x = %d\n”, &a, a); return 0; } アドレス(32bit) 中身(1記憶単位は8bit) … 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 0x 40ea 0806 0x 40ea 0807 0001 0100 0x 40ea 0808 0100 0001 0x 40ea 0809 1011 0111 0x 40ea 080a 0x 40ea 080b 0x 40ea 080c 0100 1100 0x 40ea 080d 0110 1111 0x 40ea 080e 1010 0111 0x 40ea 080f 0101 0000 0x 40ea 0810 int main(void) { int a; a = 20; printf(“a:%x = %d\n”, &a, a); return 0; } &a a 実行すると、以下の結果が出た。 a: 40ea0804 = 20 この場合のaは?  →int型(32bitの箱)の変数aは、   中身が20 (2進数では10100) 00000000 00000000 00000000 00010100 a int 型(32bit) aは、物理的にどこに存在する?  → 記憶(メモリ)の中    (OSに割り当ててもらう; 毎回変わる) aは、具体的にどこ?  → 今回は0x 40ea 0804番地からの4バイト分  → &a == 0x 40ea 0804 (aのアドレス)

アドレス(32bit), 4アドレス飛び この場合のaは? →int型(32bitの箱)の変数aは、 中身が20 (16進数では14) &a 中身(1記憶単位=8bitを4領域まとめて32bitで表示) … 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 40ea 0818 0x 40ea 081c 0x ef5c 2100 0x 40ea 0820 0x 0100 0001 0x 40ea 0824 0x 1011 0111 0x 40ea 0828 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は?  →int型(32bitの箱)の変数aは、   中身が20 (16進数では14) &a a 00000000 00000000 00000000 00010100 a int 型(32bit) 変数aのアドレスは、   0x 40ea0804番地

printf(“a:%0x = [%d, %0x]\n”, p, a.key, a.next); return 0; } アドレス(32bit), 4アドレス飛び 中身(1記憶単位=8bitを4領域まとめて32bitで表示) … 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 40ea 0818 0x 40ea 081c 0x ef5c 2100 0x 40ea 0820 0x 0100 0001 0x 40ea 0824 0x 1011 0111 0x 40ea 0828 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 struct list { int key; struct list *next; }; 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; } 変数によるプログラム: プログラム中では、 変数の枠は動かない

printf(“a:%0x = [%d, %0x]\n”, p, a.key, a.next); return 0; } &a a アドレス(32bit), 4アドレス飛び 中身(1記憶単位=8bitを4領域まとめて32bitで表示) … 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 40ea 0818 0x 40ea 081c 0x ef5c 2100 0x 40ea 0820 0x 0100 0001 0x 40ea 0824 0x 1011 0111 0x 40ea 0828 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 struct list { int key; struct list *next; }; 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 a.key a.next p 変数によるプログラム: プログラム中では、 変数の枠は動かない

printf(“a:%0x = [%d, %0x]\n”, p, a.key, a.next); return 0; } &a a アドレス(32bit), 4アドレス飛び 中身(1記憶単位=8bitを4領域まとめて32bitで表示) … 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 40ea 0818 0x 40ea 081c 0x ef5c 2100 0x 40ea 0820 0x 0100 0001 0x 40ea 0824 0x 1011 0111 0x 40ea 0828 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 struct list { int key; struct list *next; }; 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 a.key a.next p

printf(“a:%0x = [%d, %0x]\n”, p, a.key, a.next); return 0; } &a a アドレス(32bit), 4アドレス飛び 中身(1記憶単位=8bitを4領域まとめて32bitで表示) … 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 0814 0x 40ea 0818 0x 40ea 081c 0x ef5c 2100 0x 40ea 0820 0x 0100 0001 0x 40ea 0824 0x 1011 0111 0x 40ea 0828 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 struct list { int key; struct list *next; }; 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 a.key a.next p

printf(“a:%0x = [%d, %0x]\n”, p, a.key, a.next); return 0; } &a a アドレス(32bit), 4アドレス飛び 中身(1記憶単位=8bitを4領域まとめて32bitで表示) … 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 0814 0x 40ea 0818 0x 40ea 081c 0x ef5c 2100 0x 40ea 0820 0x 0100 0001 0x 40ea 0824 0x 1011 0111 0x 40ea 0828 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 struct list { int key; struct list *next; }; 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 a.key a.next p

printf(“a:%0x = [%d, %x]\n”, p, a.key, a.next); return 0; } &a a アドレス(32bit), 4アドレス飛び 中身(1記憶単位=8bitを4領域まとめて32bitで表示) … 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 0814 0x 40ea 0818 0x 40ea 081c 0x ef5c 2100 0x 40ea 0820 0x 0100 0001 0x 40ea 0824 0x 1011 0111 0x 40ea 0828 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 struct list { int key; struct list *next; }; 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 a a.key a.next p a: 40ea0800 = [20, 0] と表示

p = (struct list *)malloc(sizeof(struct list)); p->key = 21; アドレス(32bit), 4アドレス飛び 中身(1記憶単位=8bitを4領域まとめて32bitで表示) … 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 0814 0x 40ea 0818 0x 40ea 081c 0x ef5c 2100 0x 40ea 0820 0x 0100 0001 0x 40ea 0824 0x 1011 0111 0x 40ea 0828 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 struct list { int key; struct list *next; }; 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 = (struct list *)malloc(sizeof(struct list)); p->key = 21; アドレス(32bit), 4アドレス飛び 中身(1記憶単位=8bitを4領域まとめて32bitで表示) … 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 0814 0x 40ea 0818 0x 40ea 081c 0x ef5c 2100 0x 40ea 0820 0x 0100 0001 0x 40ea 0824 0x 1011 0111 0x 40ea 0828 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 struct list { int key; struct list *next; }; 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は変数 動的領域割当によるプログラム: プログラム中で、 領域を確保する (枠が増える・減る)

p = (struct list *)malloc(sizeof(struct list)); p->key = 21; アドレス(32bit), 4アドレス飛び 中身(1記憶単位=8bitを4領域まとめて32bitで表示) … 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 0814 0x 40ea 0818 0x 40ea 081c 0x 40ea 082c 0x 40ea 0820 0x 0100 0001 0x 40ea 0824 0x 1011 0111 0x 40ea 0828 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 struct list { int key; struct list *next; }; 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 = (struct list *)malloc(sizeof(struct list)); p->key = 21; アドレス(32bit), 4アドレス飛び 中身(1記憶単位=8bitを4領域まとめて32bitで表示) … 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 0814 0x 40ea 0818 0x 40ea 081c 0x 40ea 082c 0x 40ea 0820 0x 0100 0001 0x 40ea 0824 0x 1011 0111 0x 40ea 0828 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 struct list { int key; struct list *next; }; 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 = (struct list *)malloc(sizeof(struct list)); p->key = 21; アドレス(32bit), 4アドレス飛び 中身(1記憶単位=8bitを4領域まとめて32bitで表示) … 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 0814 0x 40ea 0818 0x 40ea 081c 0x 40ea 082c 0x 40ea 0820 0x 0100 0001 0x 40ea 0824 0x 1011 0111 0x 40ea 0828 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 struct list { int key; struct list *next; }; 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 = (struct list *)malloc(sizeof(struct list)); p->key = 21; アドレス(32bit), 4アドレス飛び 中身(1記憶単位=8bitを4領域まとめて32bitで表示) … 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 0814 0x 40ea 0818 0x 40ea 081c 0x 40ea 082c 0x 40ea 0820 0x 0100 0001 0x 40ea 0824 0x 1011 0111 0x 40ea 0828 21 0x 40ea 0830 0x 40ea 0834 0x 0110 1111 0x 40ea 0838 0x 1010 0111 0x 40ea 083c 0x 0101 0000 struct list { int key; struct list *next; }; 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 = (struct list *)malloc(sizeof(struct list)); p->key = 21; アドレス(32bit), 4アドレス飛び 中身(1記憶単位=8bitを4領域まとめて32bitで表示) … 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 0814 0x 40ea 0818 0x 40ea 081c 0x 40ea 082c 0x 40ea 0820 0x 0100 0001 0x 40ea 0824 0x 1011 0111 0x 40ea 0828 21 0x 40ea 0830 0x 40ea 0834 0x 0110 1111 0x 40ea 0838 0x 1010 0111 0x 40ea 083c 0x 0101 0000 struct list { int key; struct list *next; }; 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] と表示

p = (struct list *)malloc(sizeof(struct list)); p->key = 21; int key; struct list *next; }; 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 21 next NULL p-> 40ea082c = [21, 0] と表示

p = (struct list *)malloc(sizeof(struct list)); 1.メモリに割当てる p = (struct list *)malloc(sizeof(struct list)); 2.その量は、”struct list”型1個分 3.mallocの戻り値は、割当てたメモリの先頭アドレス 4.そのアドレス(参照先)の中身は “struct list”型として、「キャスト」(型変換) 5.“struct list”型へのポインタとして、アドレスを代入 この書き方は、憶えましょう。         結果は        ←これ p key 21 next NULL 要するに、 新しく「箱」ができる。 この箱に名前(変数名)はない。 だから、ポインタ変数pで指し示しておく必要がある。

free(p); この使い方も憶えましょう。 結果は ←これ malloc関数で割り当てられた この名前のない「箱」の領域は、 開放する(使わなかったことにする)ことができる。 この使い方も憶えましょう。         結果は        ←これ p 赤い箱は解放された。 つまり、このメモリは、別のプログラムや別の機会に使われる。 でも、ポインタ変数pにアドレスだけは残っている。 うっかりpの参照先に代入しようとすると、OSが怒る。(Segmentation Fault)

p = (struct list *)malloc(sizeof(struct list)); p->key = 21; アドレス(32bit), 4アドレス飛び 中身(1記憶単位=8bitを4領域まとめて32bitで表示) … 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 0814 0x 40ea 0818 0x 40ea 081c 0x 40ea 082c 0x 40ea 0820 0x 0100 0001 0x 40ea 0824 0x 1011 0111 0x 40ea 0828 21 0x 40ea 0830 0x 40ea 0834 0x 0110 1111 0x 40ea 0838 0x 1010 0111 0x 40ea 083c 0x 0101 0000 struct list { int key; struct list *next; }; 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; } a a.key a.next p key next

p = (struct list *)malloc(sizeof(struct list)); p->key = 21; int key; struct list *next; }; 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; } a 20 a.key a.next NULL p key 21 next NULL

水色の箱(変数) と 赤い箱(確保された領域) の違い 変数: a 20 ・ NULL ・変数領域 mallocによって確保された領域:  ・  ・変数領域 mallocによって確保された領域:  ・動的割当領域 a a.key 20 a.next NULL p key 21 next NULL

水色の箱(変数) と 赤い箱(確保された領域) の違い 変数: a 20 ・ブロック内で「宣言」されると、 そのブロックの中でずっと有効  ・ブロック内で「宣言」されると、  そのブロックの中でずっと有効   (スコープ)  ・  ・変数領域 mallocによって確保された領域:  ・プログラムの実行中に「割当て」。  または、「解放」。  (必要時に割り当てて、   不要になったら解放する。)  ・動的割当領域 a a.key 20 a.next NULL p key 21 next NULL

水色の箱(変数) と 赤い箱(確保された領域) の違い 変数: a 20 ・ブロック内で「宣言」されると、 そのブロックの中でずっと有効  ・ブロック内で「宣言」されると、  そのブロックの中でずっと有効   (スコープ)  ・名前(変数名)がある。  ・変数領域 mallocによって確保された領域:  ・プログラムの実行中に「割当て」。  または、「解放」。  (必要時に割り当てて、   不要になったら解放する。)  ・名前はない。  だから、アドレスを記録しなくては  ならない。  ・動的割当領域 a a.key 20 a.next NULL p key 21 next NULL

使わないのにずっと確保される「静的領域」は資源の無駄。もったいない(MOTTAINAI) 水色の箱(変数) と 赤い箱(確保された領域) の違い 変数:  ・ブロック内で「宣言」されると、  そのブロックの中でずっと有効   (スコープ)  ・名前(変数名)がある。  ・変数領域 mallocによって確保された領域:  ・プログラムの実行中に「割当て」。  または、「解放」。  (必要時に割り当てて、   不要になったら解放する。)  ・名前はない。  だから、アドレスを記録しなくては  ならない。  ・動的割当領域 a 20 a.key NULL a.next p key 21 next NULL メモリ(記憶領域)は有限な資源。 使わないのにずっと確保される「静的領域」は資源の無駄。もったいない(MOTTAINAI) 必要なときだけ、必要な量を確保し、使い終わったら解放して、他のプログラムに使ってもらおう