Title: Software 1: Practice 7
1Software 1 Practice 7
2Overview
- Structures
- Complex numbers
- Binary tree node
- Binary Trees
- Memory Allocation, Reallocation and Deallocation
3Structs Syntax
- struct complex
- double real
- double image
struct members
struct complex c struct complex pc
4Structs Syntax
- struct complex
- double real
- double image
c
5
real
image
7
int main(void) struct complex c5,7 struct
complex pc / a pointer to struct of type
complex/ c.real 5 c.image 7
5Struct Syntax
- struct complex
- double real
- double image
6024
c
3
5
real
int main(void) struct complex c struct
complex pc c.real 5 c.image 7 pc
c pc-gtreal 3 pc-gtimage 4
4
image
7
pc
6Struct Syntax
- There are two equivalent option to access the
fields of a pointer to struct - When accessing the fields of a pointer to struct
you should be sure that it points to allocated
memory!!!
pc-gtreal 3
(pc).real 3
7Example
void print_complex (struct complex
num) printf(lf lf i\n, num.real,
num.image) void scan_complex(struct complex
p_num) scanf(lflf, p_num-gtreal,
p_num-gtimage)
8Problem
- Write a function abs_complex, which receives a
complex number and returns it absolute value - Write a function add_complex, which receives
two complex numbers and returns their sum
(complex number).
9- double abs_complex(struct complex a)
- return a.image a.image a.real a.real
-
- struct complex add_complex(struct complex a,
struct complex b) - struct complex s
- s.image a.image b.image
- s.real a.real b .real
- return s
-
Passed by value!!
Usage x add_complex(x,y) ab
abs_complex(x)
10Definition of Data Types
- struct complex
- double real
- double image
-
- int main()
-
- struct complex c5,7
- struct complex pc
-
struct complex double real double
image typedef struct complex complex_t int
main() complex_t c5,7 complex_t pc
typedef struct complex complex_t
Existing struct name
Definition of new type
11Binary Tree Node
- typedef struct node
- struct node right
- struct node left
- int value
- Node
value
Left
Right
value
value
struct node struct node right struct
node left int value typedef struct node
Node
12Node allocation and initialization
Returns the new node
Allocate the memory for the new node.
- Node create_node(int value)
-
- Node tmp (Node ) malloc(sizeof(Node))
- if (!tmp)
- fprintf(stderr, "ERROR not enough
memory!\n") - return NULL
-
- tmp-gtleft tmp-gtright NULL
- tmp-gtvalue value
- return tmp
-
Verify the correct allocation.
Initialize
13Traversing a Binary Tree
P
L
R
- void print_tree(Node root)
-
- if (!root) return
- print_tree(root-gtleft)
- printf("d ", root-gtvalue)
- print_tree(root-gtright)
-
Null Null Null Null
If finished traversing
Recursive call to print the left child
Print the value of the current node.
Recursive call to print the right child
14- Node insert(Node root, int value)
- Node parent
- Node child
- Node new_node
- new_node create_node(value)
- if (!new_node) return NULL
- if (!root) return new_node
- child root
- while (child)
- parent child
- if (child-gtvalue gt value)
- child child-gtleft
- else
- child child-gtright
-
- if (parent-gtvalue gt value)
- parent-gtleft new_node
Inserts a given value into a tree pointed by root
Allocate the memory and create the new node
new_node
root
4
7
3
9
2
5
parent
15Operations on structures
typedef struct ..
- Define structures
- Declare variables of structure type
- Assign entire structures
- Pass as arguments to functions
- Define functions which return structures
- Initialize a structure variable (comma-separated
list of values enclosed in braces )
Node node
node1 node2
Node node NULL, NULL, 0
16Pointer to Function
- A functions that prints the value of a node
- void print_node(void value)
- printf("d ", (int) value)
-
- We want to pass the print function as parameter
in the - following manner
- traverse_tree(root, print_node)
17Pointer to Function
- Define a type a pointer to function which (in the
case of print_node) - Accepts void as a parameter
- Returns void
typedef void(Op)(void )
Function parameter
Return value
18Traversing a Binary Tree
- void traverse_tree(Node root, Op op)
-
- if (!root) return
- traverse_tree(root-gtleft, op)
- op((void )root-gtvalue)
- traverse_tree(root-gtright, op)
-
Usage traverse_tree(root, print_node)
The function passed through the pointer op will
be called
19- include ltstdio.hgt
- int add(int x, int y) / declare function /
- int main()
- int x6, y9
- int (ptr)(int, int) / declare pointer to
function/ - ptr add / set pointer to point to "add"
function / - printf("d plus d equals d.\n", x, y,
(ptr)(x,y)) - / call function using pointer /
- return 0
-
- int add(int x, int y) / function definition /
- return xy
Equivalent to int (ptr)(int x, int y)
20Memory Allocation
- Dynamically allocated regions of storage are like
arrays. Use array-like subscripting notation on
them. - Keep track of the allocated memory.
- It is easy to accidentally use a pointer which
points "nowhere. It can point "somewhere", just
not where you wanted it to!!!
the 0 gets written "somewhere"
p 0
21Allocating memory for characters
- All strings have a terminating '\0' character.
- Add 1 to the count that strlen return when
calling malloc
char somestring, copy / allocate and initiate
somestring / ... copy (char )
malloc(strlen(somestring) 1) / 1 for \0 /
/ check malloc's return value / strcpy(copy,
somestring)
22Allocating memory for integers
- Goal allocate an array for 100 integers
- It's much safer and more portable to let C
compute the size. - Use the sizeof() operator, that computes the
size, in bytes, of a variable or type
int ip (int ) malloc(100 sizeof(int))
sizeof() is an operator, and it is evaluated at
compile time
Can be accessed as ip0, ip1, ... up to
ip99
23Verifying allocated memory
- No real computer has an infinite amount of memory
available. - No guarantee that malloc will be able to give us
as much memory as we ask for. - malloc returns a null pointer upon failure.
- It's vital to check the returned pointer before
using it!!
int ip (int ) malloc(100 sizeof(int)) if
(ip NULL) printf("ERROR out of
memory\n") return -1
24Freeing memory
- Memory allocated with malloc does not
automatically disappear when a function returns,
as automatic-duration variables do. - The allocated memory does not have to remain for
the entire duration of your program. - Memory is not inexhaustible.
- Deallocate (free) memory when you don't need it
any more - p contains a pointer previously returned by
malloc
free(p)
25Recycling memory
- Freeing memory is recycling
- It costs you almost nothing
- The memory you give back is immediately usable by
other parts of your program. (Theoretically, it
may even be usable by other programs.) - Freeing unused memory is a good idea, but it's
not mandatory - Allocated memory is automatically released upon
exit by the operating system
26Recycling memory
- Once you've freed some memory you must remember
not to use it any more - After calling free(p) p still points at the
same memory - Do not use the memory pointed to by p after
free(p)
while (ptr ! NULL) free(ptr) ptr
ptr-gtnext
Illegal reference to the freed memory.
27Keeping track
- There is a big difference between a pointer and
what it points to. You need at least one pointer
to the memory to use it or free it. - Suppose
- you store the pointer that malloc gives you in a
local pointer variable - then, the function containing the local pointer
variable returns - local variables have automatic duration
- The pointer disappears when the function returns,
but the memory remains allocated - there is no way to use it or free it, if it
contained the only copy of the pointer
28Reallocating memory
- realloc - accepts an old pointer and a new size
- returns contiguous space of the new size
-
- If the old block can be made bigger, it returns
the same pointer - otherwise, it
- Attempts to allocate new memory
- If successful
- Copies old data to new memory
- Frees old memory block
- Returns new pointer
- Otherwise, returns NULL
ip realloc(ip, 200 sizeof(int))
29Realloc Example
- A program that reads lines of text from the
standard input. - Each line is treated as an integer by calling
atoi. - atoi - converts strings, like "23" or even
"29dhjds" into integers (returning 23 and 29
respectively in this case). - If the string is empty, or first character isn't
a number or a minus sign, then atoi returns 0. - If atoi encounters a non-number character, it
returns the number formed up until that point. - Each integer is stored in a dynamically-allocate
d "array.
30- include ltstdlib.hgt
- include ltstdio.hgt
- define MAXLINE 100
- define INITSIZE 2
- int main()
-
- char lineMAXLINE
- int ip
- int nalloc, nitems
- nalloc INITSIZE
- ip (int ) malloc(nalloc sizeof(int)) /
initial allocation / - if (ip NULL)
- printf("out of memory\n")
- return -1
-
Will store the line
The array of numbers
The number of allocated positions and items
Allocate the initial array
31- nitems 0
-
- while (getline(line, MAXLINE) ! EOF)
- if (nitems gt nalloc) / increase
allocation / - int newp
- nalloc 2
- newp realloc(ip, nalloc sizeof(int))
- if (newp NULL)
- printf("out of memory\n")
- return -1
-
- ip newp
-
- ipnitems atoi(line)
-
- printf("Allocated d items, initialize d
items\n", nalloc, nitems) - return 0
getline() reads one line from standard input and
copies it to line array (see the handout).
Reallocate the memory
Write to the reallocated memory.