Title: Programming
1Programming
- Structures andDynamic Allocation
2Dynamic Memory Allocation
- The memory requirement of our program is not
always known in advance - Arrays have fixed size determined at compile
time - We would like to allocate at runtime
3The Memory
- Two Parts
- Stack
- Memory is allocated when entering a function
- Deallocation when the function terminates
- Heap
- Programmer control allocation and deallocation
4Memory Management
- stdlib.h
- Two operations for memory management
- Allocation
- void malloc()
- Deallocation
- void free()
5The malloc Function
- void malloc(unsigned int nBytes)
- malloc is used to dynamically allocate nBytes in
memory - malloc returns a pointer to the allocated area on
success, NULL on failure - You should always check whether memory was
successfully allocated - Remember to include ltstdlib.hgt
6The free Function
- void free(void ptr)
- Use free(p) to deallocate memory pointed by p
- If p doesnt point to an area allocated by malloc
an error occurs - No partial deallocation
- Always remember to free the allocated memory once
you are done with it
7Example
- int main(void)
-
- int i, n, p
- printf("How many numbers will you enter?\n")
- scanf("d", n)
- / Allocate an int array of the proper size
/ - p (int)malloc(n sizeof(int))
- if (p NULL)
-
- printf("Memory allocation failed!\n")
- return 1
-
- ...
- / Free the allocated space /
- free(p)
8Why Casting?
The casting in p (int )malloc(nsizeof(int))
is needed because malloc returns void void
malloc(unsigned int nbytes) The type (void)
specifies a general pointer, which can be cast to
any pointer type.
9What is sizeof ?
- The sizeof operator gets a variable or a type as
an input and return its size in bytes - sizeof always calculates the size of the type
-
- double x
- s1 sizeof(x) / s1 is 8 /
- s2 sizeof(int) / s2 is 4 /
-
10Example
- char name25char address (char)malloc(25)
int i - printf("sizeof(name) d\n", sizeof(name))
- printf("sizeof(address) d\n",
sizeof(address)) - if (sizeof(i) sizeof(address))
- printf("True\n")
- else
- printf("False\n")
254True
11Returning Allocated Memory
- Since allocated memory is not deallocated upon
function termination we can return its address. - Duplicate a string
char strdup(const char str) char dup
(char)malloc((strlen(str)1)
sizeof(char)) if (dup ! NULL)
strcpy(dup, str) return dup
12Exercise
- Implement the functionchar my_strcat(const char
s1, const char s2) - Output a pointer to a dynamically allocated
concatenation of s1 and s2 - For example The concatenation of hello_ and
world! is the string hello_world! - Test your function
13Solution
- char my_strcat(const char s1, const char s2)
-
- int len char result NULL
- len strlen(s1) strlen(s2) 1
- result (char)malloc(len sizeof(char))
- if (result NULL)
- printf(Memory allocation failed!\n")
- return NULL
-
- strcpy(result, s1)
- strcat(result, s2)
- return result
14Whats Wrong Here?
- char my_strcat(const char s1, const char s2)
-
- int len
- char result500 / assume this is enough /
- strcpy(result, s1)
- strcpy(result strlen(s1), s2)
- return result
15Pitfalls
- Accessing un-initialized pointer int p p
3 - Using de-allocated memory int p
(int)malloc(SIZE sizeof(int)) ... / do
something with p/ free(p) p 0
16Structures
- Not much in the real world comes to us as simple
data types. (e.g. Car, Book, Bank account) - We want to be able to manipulate logical entities
as a whole - The individual pieces of the data may exist in
one of the basic forms - How do you keep track of what pieces of the data
belong together?
17Examples
- Book
- Title, Authors, ISBN, Publisher
- Bank Account
- Owners, Balance, Credit
- Car
- Make, Model, Year
18Structures - User Defined Types
- A convenient way of grouping several pieces of
related information together. - A collection of variables under a single name.
19Structures - Example
- struct point double x double y
- struct rectangle struct point low_left
struct point up_right - struct student
- char id10
- char name
- int avg_grade
struct point double x, y
20Defining a struct
- struct struct-name
- type field-name1 type field-name2
type field-name3 - ...
21Example - Rational Numbers
- Structure declaration
- Variable definition
- Define variables of type rational
struct rational int numerator,
denominator
struct rational r1, r2
22Field Access
- Use the . (dot) operator to access a field in a
structure ltvariable namegt.ltfield namegt - If rat is of type rational then to access the
numerator part we write rat.numeratorand to
access the denominator part we write rat.denomina
tor
23Example
- Printing a rational number
- printf("d / d", rat.numerator,
rat.denominator) - Input from the user
- scanf("d", rat.numerator)
24Exercise
- Define a struct named time.
- time contain hour, minute and second
- Write a program that reads the current time from
the user and store it in a time structure, then
it prints the time.
25Solution
- struct time
- int hour, minute, second
-
- int main()
-
- struct time t
- printf("Enter the current time (HHMMSS)
") - scanf("ddd", t.hour, t.minute,
t.second) - printf("The current time is
02d02d02d\n", - t.hour, t.minute, t.second)
- return 0
-
26Typdef
- Introduce synonyms for types typedef int
Boolean typedef char StringBoolean
bString str "Text"
27Typdef and Structs
- Instead of writing struct rational everywhere we
can create a shorter synonym using typedef. - typdef struct rational Rational
- Then use it
- Rational r1, r2
28Typedef Even Shorter
- We can combine the typdef with the structure
declaration - typedef struct rational
- int numerator
- int denominator
- Rational
- This is the common way to define new types
29Exercise
- Change your definition of time to use typedef.
- Change your program to use the new alias
30Structures and Functions
- Function can receive structures as their
parameters and return structures as their return
value - Parameter passing is done by value
- copy
- Similar to basic types
31Structures and Functions - Example
- Rational make_rational(int n, int d)
Rational temp temp.numerator n
temp.denominator m - return temp
-
- Rational rat_mul(Rational r1, Rational r2)
-
- return make_rational((r1.n r2.n), (r1.d
r2.d))
32rat_mul step by step
- int main(void)
-
- Rational a, b, mul
- printf("first rational ")
- scanf("dd", (a.n), (a.d))
- printf("second rations ")
- scanf("dd", (b.n), (b.d))
- mul rat_mul(a, b)
- printf("result d / d\n", mul.n, mul.d)
- return 0
mul
d
n
33rat_mul step by step
- int main(void)
-
- Rational a, b, mul
- printf("first rational ")
- scanf("dd", (a.n), (a.d))
- printf("second rations ")
- scanf("dd", (b.n), (b.d))
- mul rat_mul(a, b)
- printf("result d / d\n", mul.n, mul.d)
- return 0
mul
d
n
34rat_mul step by step
- int main(void)
-
- Rational a, b, mul
- printf("first rational ")
- scanf("dd", (a.n), (a.d))
- printf("second rations ")
- scanf("dd", (b.n), (b.d))
- mul rat_mul(a, b)
- printf("result d / d\n", mul.n, mul.d)
- return 0
mul
d
n
35rat_mul step by step
- int main(void)
-
- Rational a, b, mul
- printf("first rational ")
- scanf("dd", (a.n), (a.d))
- printf("second rations ")
- scanf("dd", (b.n), (b.d))
- mul rat_mul(a, b)
- printf("result d / d\n", mul.n, mul.d)
- return 0
mul
d
n
36rat_mul step by step
- int main(void)
-
- Rational a, b, mul
- printf("first rational ")
- scanf("dd", (a.n), (a.d))
- printf("second rations ")
- scanf("dd", (b.n), (b.d))
- mul rat_mul(a, b)
- printf("result d / d\n", mul.n, mul.d)
- return 0
mul
d
n
37rat_mul step by step
b
- int main(void)
-
- Rational a, b, mul
- printf("first rational ")
- scanf("dd", (a.n), (a.d))
- printf("second rations ")
- scanf("dd", (b.n), (b.d))
- mul rat_mul(a, b)
- printf("result d / d\n", mul.n, mul.d)
- return 0
d
n
2
4
mul
d
n
38rat_mul step by step
- Rational rat_mul(Rational r1, Rational r2)
-
- return make_rational((r1.n r2.n),
- (r1.d r2.d))
r2
d
n
2
4
39rat_mul step by step
- Rational make_rational(int n, int d)
-
- int g
- Rational result
- if (d 0) ...
- if (d lt 0)
- d -1
- n -1
-
- g gcd(n, d)
- result.n n / g
- result.d d / g
- return result
40rat_mul step by step
- Rational make_rational(int n, int d)
-
- int g
- Rational result
- if (d 0) ...
- if (d lt 0)
- d -1
- n -1
-
- g gcd(n, d)
- result.n n / g
- result.d d / g
- return result
41rat_mul step by step
- Rational make_rational(int n, int d)
-
- int g
- Rational result
- if (d 0) ...
- if (d lt 0)
- d -1
- n -1
-
- g gcd(n, d)
- result.n n / g
- result.d d / g
- return result
42rat_mul step by step
- Rational make_rational(int n, int d)
-
- int g
- Rational result
- if (d 0) ...
- if (d lt 0)
- d -1
- n -1
-
- g gcd(n, d)
- result.n n / g
- result.d d / g
- return result
43rat_mul step by step
- Rational make_rational(int n, int d)
-
- int g
- Rational result
- if (d 0) ...
- if (d lt 0)
- d -1
- n -1
-
- g gcd(n, d)
- result.n n / g
- result.d d / g
- return result
44rat_mul step by step
- Rational make_rational(int n, int d)
-
- int g
- Rational result
- if (d 0) ...
- if (d lt 0)
- d -1
- n -1
-
- g gcd(n, d)
- result.n n / g
- result.d d / g
- return result
45rat_mul step by step
- Rational rat_mul(Rational r1, Rational r2)
-
- return make_rational((r1.n r2.n),
- (r1.d r2.d))
r2
d
n
2
4
46rat_mul step by step
b
- int main(void)
-
- Rational a, b, mul
- printf("first rational ")
- scanf("dd", (a.n), (a.d))
- printf("second rations ")
- scanf("dd", (b.n), (b.d))
- mul rat_mul(a, b)
- printf("result d / d\n", mul.n, mul.d)
- return 0
d
n
2
4
mul
d
n
1
4
47rat_mul step by step
b
- int main(void)
-
- Rational a, b, mul
- printf("first rational ")
- scanf("dd", (a.n), (a.d))
- printf("second rations ")
- scanf("dd", (b.n), (b.d))
- mul rat_mul(a, b)
- printf("result d / d\n", mul.n, mul.d)
- return 0
d
n
2
4
mul
d
n
1
4
48Exercise
- Implement the function void print_time(Time t)
- Change your program to use this function
49Assignment
- Structures can be assigned (copied) using the
assignment operator - Bitwise copy copying the content of one
structures memory onto another - r1 add_rat()
1001001110101010010101010101110101110101
0000000000000000000000000000000000000000
1001001110101010010101010101110101110101
c1
c2
50Arrays in Structs
- The entire array is part of the structure
- When passing the struct to a function (by value)
- Changing the array field wont change the
original array
51Pointers in Structs
- When copying a struct containing a pointer only
the pointer is copied (shallow copy) - Not what the pointer points to
- we should take extra care when manipulating
structures that contain pointers
52Comparison
- Structures cannot be compared using the equality
operator - They must be compared member by member
- Usually this will be done in a separate function
int is_equal(Rational r1, rational r2)
return (r1.n r2.n) (r1.d r2.d)
53Pointers to Structures
- Same as with other types
- Pointer definition
- structure-name variable-name
- Rational rat_ptr
defines a rational and a pointer to a rational
Rational r, rptrrptr r
assign the address of the rational variable to
the rational pointer
54Accessing Fields Using Pointers
Rational rRational pr r
- To access the fields we can write(pr).n(pr).
d
55Alternative Syntax
- Pointer to structures are extremely common
- Alternative notation as a shorthand
- p?member-of-structure
- ? is minus sign followed by gt
- Example
- pr?n
- pr?id
56Example
- typdef struct point double x, y
Pointtypdef struct rect Point pt1,
pt2 RectRect r, rp rr.pt1.x(rp).pt1
.xrp-gtpt1.x
equivalent
57Example
- typedef struct point
-
- double x
- double y
- Point
- typedef struct circle
-
- Point center
- double radius
- Circle
58Example
A point is in a circle if its distance from the
center is smaller than the radius.
- int is_in_circle(Point p, Circle c)
-
- double x_dist, y_dist
- x_dist p-gtx - c-gtcenter.x
- y_dist p-gty - c-gtcenter.y
- return (x_dist x_dist y_dist y_dist lt
c-gtradius c-gtradius)
59Exercise
- Implement the functionTime time_update(const
Time t, Time delta) - The function accepts a time and adds to it the
delta. Make sure the result is legal. - Write a program that accepts a time from the user
and adds to it 1 hour, 27 minues and 3 seconds.
Print the result.
60Exit
- void exit(int status)
- Sometimes an error occurs and we want the program
to immediately exit (e.g. division by zero,
memory allocation failure) - exit terminates the program
- de-allocates all resources (close open files,
free memory, ) - To be used only in extreme situations
- Remember to include ltstdlib.hgt