計算機実習 I

第十回 (2015 年 6 月 11 日)

ポインタの応用: 動的メモリ

http://www.sw.it.aoyama.ac.jp/2015/CP1/lecture10.html

Martin J. Dürst

AGU

© 2005-15 Martin J. Dürst 青山学院大学

今日の予定

ミニテスト

前回の演習結果

09A1 09A2 09A3 09B1 09C1 09C2
100点 75 77 79 43 40 43
60点 19 17 14 49 48 46
エラー - - 1 1 3 1
未提出 - - 1 3 4

配置のメモリ配置 (09C2)

 

プログラミングへの心構え

ポインタの用途

先週のまとめ

ポインタの方程式

方程式の応用例

&array[i] の単純化:
&(array[i])
&(*(array+i))
&*(array+i)
(array+i)
array+i

配列方式からポインタ方式への変換: 出発点

int countUpper (char string[])
{
int i;
int count = 0;
int length = strlen(string);

for (i=0; i<length; i++)
if (isupper(string[i]))
count++;
return count;
}

 

配列方式からポインタへ方式の変換: 到着点

int countUpper (char *string)
{
int count = 0;
while (*string)
if (isupper(*string++))
count++;
return count;
}

 

配列方式とポインタ方式の特長

注意: 特別な指示がない限り、プログラムは配列方式でもポインタ方式でも提出可能 (読みやすさ重視)

 

演習 10B1: 用語の再確認

スタック:
関数内の変数が、関数の呼ばれる順番に配置される領域
ヒープ:
動的メモリの領域
グローバル変数:
関数の外に定義されている変数
関数内の static な変数:
関数が終わっても残る変数
ローカル変数:
関数の中に定義されている変数

 

メモリの使い方

メモリは変数などの種類によってに分けられ、使用領域が違う。典型例:


FFFFFFFF

スタック: ローカル変数、引数、関数呼び出しに必要なもの

↓↓↓↓↓↓↓↓ 下方向に伸び、使用後縮む ↑↑↑↑↑↑↑↑

 
空き領域
 

↑ ↑ ↑ ↑ ↑ ↑ およそ上方向に伸びる ↑ ↑ ↑ ↑ ↑ ↑

ヒープ: プログラム中任意に必要なメモリ

初期値を持たないグローバル変数

初期値を持つグローバル変数

関数などプログラムそのもの
00000000

 

ヒープの使い方

 

動的メモリの定石

(pattern)

 

定石の説明

if (!(              // メモリが足りるかのテスト
my_array = // 新しいメモリ領域のアドレスをポインタへ代入
(int *) // my_array のポインタ型への変換
malloc( // 関数の呼び出し
sizeof(int) // my_array の一つの要素の大きさ
* asize) // メモリ領域の大きさの計算
))
printf("Not enough memory!\n") // エラーの通知
, // 順次演算子
exit(1); // プログラムの強制終了

 

動的メモリの関数

 

動的メモリの注意点

void *

NULL ポインタ

演習問題について

演習の前の作業

次回の準備