Applications of Pointers I: Memory Management,
Dynamic Memory
(ポインタの応用 II:
メモリ操作、動的メモリ)
Computing Practice I
10th lecture, June 14, 2018
http://www.sw.it.aoyama.ac.jp/2018/CP1/lecture10.html
Martin J. Dürst
© 2005-18 Martin
J. Dürst 青山学院大学
Today's Schedule
- Minitest
- Equations for pointers
- Overall memory layout of a program
- Dynamic memory
void *
and NULL
pointers
- Today's exercises
ミニテスト
- 授業開始までにログイン済み
- ナビゲーションは左に畳み、ブラウザは全画面に拡大
- 授業開始まで教科書、資料、筆箱、財布などを鞄に入れ、鞄を椅子の下に
- テスト終了後その場で待つ
Homework from Last Week
Collection of 09C2 memory layout
Results of Previous Exercises
|
09A1 |
09A2 |
09A3 |
09B1 |
09C1 |
09C2 |
100 points |
80 |
76 |
76 |
48 |
47 |
55 |
60 points |
19 |
23 |
23 |
48 |
47 |
38 |
errors |
- |
- |
- |
3 |
3 |
2 |
not submitted |
1 |
1 |
1 |
1 |
3 |
5 |
Memory Layout of Arrays (09C2)
- Array of pointers to strings:
char *month_names[] = { ...
- Separate pointers need extra memory
- Actual strings can be stored compactly
- Array of strings
char month_names[][10] = { ...
- No need for separate pointers
- Length of longest string (+1) has to be give explicitly
- Potentially wasteful because all strings need the same amout of
space
Summary of Last Lecture
- Memory locations are identified by addresses
- Pointers are variables containing addresses
- Pointers have types: pointer to
int
, ...
&
(address operator) obtain the address of a
variable
*
(indirection operator) obtains the data pointed to by a
pointer
- Integers can be added to or substracted from pointers
- By adding
1
, a pointer moves by the size of one item of the
type it points to
Usages of Pointers
- Low-level address manipulation (device allocation,...)
- Speedup of array processing
- Dynamic memory management
- Reference (passing of arguments to a function by reference,...)
- Indirection
Equations for Pointers
*&
v ≡ v
(if v is a variable)
&*
p ≡ p
(if p is a pointer/array)
*(
p+
i)
≡
p[
i]
≡
i[
p]
( i[
p]
not recommended at
all)
(if p is a pointer/array)
(*
sp).
m ≡
sp->
m
(if sp is pointing to a structure)
Example of Using Equations
Simplifying &array[i]
:
→ &(array[i])
→ &(*(array+i))
→ &*(array+i)
→ (array+i)
→ array+i
Conversion from Array Notation to Pointer Notation: Start
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;
}
Conversion from Array Notation to Pointer Notation: Goal
int countUpper (char *string)
{
int count = 0;
while (*string)
if (isupper(*string++))
count++;
return count;
}
Properties of Pointer Notation and Array Notation
- Pointer notation:
- Often no need for a loop variable, shorter code
- Fast execution (even with old compilers)
- Easy to optimize
- Array notation:
- Easier to understand for more programmers
- Can be optimized by newer compilers
Attention: If there are no specific instructions, programs can be submitted
either using array notation or pointer notation (or a mixture; please care
about readability)
Exercise 10B1: Vocabulary Check
- Stack:
- Memory area where local variables (and function arguments, return
addresses, and stack pointers) are laid out for each function
invocation
- Heap:
- Memory area for dynamic memory
- Global variable:
- Variable declared outside of a function
- Local variable:
- Variable declared inside a function
static
variable (declared inside a function):
- Variable that persists between function invocations
Memory Layout
The memory area where each variable is allocated differs for different kinds
of variables.
Typical example:
FFFFFFFF |
|
|
Stack: Local variables, function arguments, other data necessary for
function call |
|
↓↓↓↓↓↓↓↓ grows
downwards, shrinks upwards after usage
↑↑↑↑↑↑↑↑ |
|
Empty area
|
|
↑ ↑ ↑ ↑ ↑ ↑ grows upwards, usually does not shrink ↑
↑ ↑ ↑ ↑ ↑ |
|
Heap: Memory needed at arbitrary points during program execution |
|
Un-initialized global variables without |
|
Initialized global variables |
|
The actual program (functions,...) |
00000000 |
|
Usage of Heap
- Some memory is needed during program execution, but it is not clear how
much
- Main usage examples: Data structures where the number of elements is
unknown and difficult to predict (arrays (e.g. 10C1.c), trees, lists (e.g.
10C2main.c),...)
- Usage:
- When memory is needed, allocate (using
malloc
,...)
- When memory is no longer needed, deallocate (using
free
)
- Automated in many programming languages (but not C/C++) by using garbage
collection
Dynamic Memory Patterns
Explanation of Memory Allocation Pattern
if (!( // test whether there is enough memory
my_array = // assign address of new memory region to pointer
(int *) // cast pointer to desired type
malloc( // call allocation function
sizeof(int) // size of a single element of my_array
* asize) // multiplied by the number of elements
))
printf("Not enough memory!\n") // error message
, // comma (sequence) operator
exit(1); // force end of program execution
Dynamic Memory Functions
malloc
: Allocate memory region
calloc
: Allocate memory region and initialize with 0es
realloc
: Reallocate memory region
new_location =
realloc(old_location、new_size);
pNew = realloc(pOld, 10);
(and do not forget to use the memory allocation pattern here, too)
free
: Freeing (deallocation) of memory region
Dynamic Memory: Cautions
- The size of the allocated memory region has to be managed by the
programmer
realloc
, free
can only be used with pointers to
the start of a memory region
- Never use freed or reallocated memory!
- Clearly define responsibility for allocation and deallocation
(Example: Allocation inside function, deallocation by the caller (10B2,
10C2))
- Always free all no longer used memory (avoid memory leaks)
void *
- The return type of
malloc
,... is void *
void *
is a pointer not pointing to any specific data type
(just raw memory)
- To use, convert to an ordinary pointer type
malloc
,... return (void*)0
when there is not
enough memory
NULL
Pointer
- If a pointer does not point anywhere,
NULL
is used
- Use (dereferencing) of
NULL
produces an error (segmentation
fault,...)
→ In many cases, a check befor use is necessary
- The following are different concepts, but represented the same way in C:
NULL
(null pointer)
0
(number zero)
'\0'
(null character)
- "false"
演習問題について
- 10A1: 構造体の効率的なメモリの使用 (必ず自分の PC
で完了してから提出)
- 10B1: プログラムのメモリ配置 (紙の提出のみ)
- 10B2: 動的メモリ
(
malloc
、テストファイルあり)
- 10C1: 配列と動的メモリ (ポインタ方式、
[]
は使用禁止)
- 10C2: 10B2 の発展
(
realloc
、挑戦は必須、完成は発展問題、月曜日締切、部分点)
次回の準備
- 宿題として残った問題を完成、提出
- 今日の復習
- 「ポインタが理解できない理由」の第六章 「malloc
とポインタ」(浅井 淳、技術評論社、2002)
をもう一回よく読む。
- 参考書の第 11 章 (ポインタ、pp. 282-311)
をもう一回よく読む。分からないところがあればよく調べる。
Glossary
- dynamic memory
- 動的メモリ
- pattern
- ひな形、模型、定石
- memory allocation
- メモリの確保
- comma operator (sequence operator)
- コンマ演算子 (順序演算子)
- garbage collection
- ゴミ集め