# Applications of Pointers I: Memory Management, Dynamic Memory

(ポインタの応用 II： メモリ操作、動的メモリ)

## Computing Practice I

### 10th lecture, June 22, 2017

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

### Martin J. Dürst

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

# Today's Schedule

• Minitest
• Equations for pointers 09
• 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 92 92 93 56 59 60 60 points 6 6 5 42 37 36 errors - - - - 2 - not submitted 1 1 1 1 1 3

# 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

1. Low-level address manipulation (device allocation,...)
2. Speedup of array processing
3. Dynamic memory management
4. Reference (passing of arguments to a function by reference,...)
5. Indirection

# Equations for Pointers

• `*&`vv
(if v is a variable)
• `&*`pp
(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`).`msp`->`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 many 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

• Including the necessary header file:
`#include <stdlib.h>`
• Decide on length (number of items) and define a pointer:
`int masize = 10;```` int *my_array;```
• Memory allocation:
```if (!(my_array = (int *) malloc(sizeof(int)*masize)))
printf("Not enough memory!\n"), exit(1);```
• Use:
`my_array[5] = 500;`
• Freeing the allocated memory region:
`free (my_array);`

# 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);```
• `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
• `NULL` (null pointer), `0` (number zero), `'\0'` (null character), and "false" are different concepts, but represented in the same way in C

# 演習問題について

• 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
ゴミ集め