1 Structures, Dynamic Memory Allocation. 2 Agenda Structures Definition & usage Pointers to...
-
date post
21-Dec-2015 -
Category
Documents
-
view
246 -
download
4
Transcript of 1 Structures, Dynamic Memory Allocation. 2 Agenda Structures Definition & usage Pointers to...
1
Structures, Structures, Dynamic Dynamic Memory Memory
Allocation Allocation
2
Agenda
Structures Definition & usage Pointers to structures Arrays and pointers in structures
Dynamic Memory Allocation
3
Structures
‘Logical entities’ Examples: complex numbers, dates,
student records, geometric objects, etc’
Each is composed of a number of variables
4
Structures
struct: collection of variables, gathered into one variable
Defines new data types Memory Variables in a struct are called
members or fields
5
Example – complex numbers
Definition of a new ‘type’ that represents a complex number:
struct complex { int real; int img; };
Once we define a structure, we can use it as any type:
struct complex num1, num2, num3;
6
Access structure members If A is of some structure with a member
named x, then A.x is that member of Astruct complex C;C.real = 0;
If A is a pointer to a structure with a member x, then A->x is that member of the variable pointed by A (same as (*A).x)struct complex *pc = &C;pc->real = 1;
7
Convenient usage with typedef
typedef struct complex_t { int real; int img; } complex;
A new variable type: “complex” Saves writing “struct complex” every
time! Usage: complex num1, num2;
8
Examples (AddComplex.c)
complex AddComp (complex x, complex y) { complex z;
z.real = x.real + y.real; z.img = x.img + y.img;
return z;}
Structures are passed to functions “by value”
A copy of the structure is passed
9
AddComplex – step by step
complex a, b, c;
printf(“…");scanf("%lf%lf",&(a.real),&(a.img));printf(“…");scanf("%lf%lf",&(b.real),&(b.img));
c = AddComp(a,b);
printf(“result = %g+%gi\n",c.real,c.img);return 0;
… …
real
img
a
… …
real
img
b
… …
real
img
c
10
AddComplex – step by step
complex a, b, c;
printf(“…");scanf("%lf%lf",&(a.real),&(a.img));printf(“…");scanf("%lf%lf",&(b.real),&(b.img));
c = AddComp(a,b);
printf(“result = %g+%gi\n",c.real,c.img);return 0;
… …
real
img
a
… …
real
img
b
… …
real
img
c
11
AddComplex – step by step
complex a, b, c;
printf(“…");scanf("%lf%lf",&(a.real),&(a.img));printf(“…");scanf("%lf%lf",&(b.real),&(b.img));
c = AddComp(a,b);
printf(“result = %g+%gi\n",c.real,c.img);return 0;
1.0 2.0
real
img
a
… …
real
img
b
… …
real
img
c
12
AddComplex – step by step
complex a, b, c;
printf(“…");scanf("%lf%lf",&(a.real),&(a.img));printf(“…");scanf("%lf%lf",&(b.real),&(b.img));
c = AddComp(a,b);
printf(“result = %g+%gi\n",c.real,c.img);return 0;
1.0 2.0
real
img
a
… …
real
img
b
… …
real
img
c
13
AddComplex – step by step
complex a, b, c;
printf(“…");scanf("%lf%lf",&(a.real),&(a.img));printf(“…");scanf("%lf%lf",&(b.real),&(b.img));
c = AddComp(a,b);
printf(“result = %g+%gi\n",c.real,c.img);return 0;
1.0 2.0
real
img
a
3.0 4.0
real
img
b
… …
real
img
c
14
AddComplex – step by step
complex a, b, c;
printf(“…");scanf("%lf%lf",&(a.real),&(a.img));printf(“…");scanf("%lf%lf",&(b.real),&(b.img));
c = AddComp(a,b);
printf(“result = %g+%gi\n",c.real,c.img);return 0;
1.0 2.0
real
img
a
3.0 4.0
real
img
b
… …
real
img
c
15
AddComplex – step by step
complex AddComp(complex x, complex y){ complex z;
z.real = x.real + y.real; z.img = x.img + y.img;
return z;}
1.0 2.0
real
img
x
3.0 4.0
real
img
y
… …
real
img
z
16
AddComplex – step by step
complex AddComp(complex x, complex y){ complex z;
z.real = x.real + y.real; z.img = x.img + y.img;
return z;}
1.0 2.0
real
img
x
3.0 4.0
real
img
y
… 6.0
real
img
z
17
AddComplex – step by step
complex AddComp(complex x, complex y){ complex z;
z.real = x.real + y.real; z.img = x.img + y.img;
return z;}
1.0 2.0
real
img
x
3.0 4.0
real
img
y
4.0 6.0
real
img
z
18
AddComplex – step by step
complex AddComp(complex x, complex y){ complex z;
z.real = x.real + y.real; z.img = x.img + y.img;
return z;}
1.0 2.0
real
img
x
3.0 4.0
real
img
y
4.0 6.0
real
img
z
19
AddComplex – step by step
complex a, b, c;
printf(“…");scanf("%lf%lf",&(a.real),&(a.img));printf(“…");scanf("%lf%lf",&(b.real),&(b.img));
c = AddComp(a,b);
printf(“result = %g+%gi\n",c.real,c.img);return 0;
1.0 2.0
real
img
a
3.0 4.0
real
img
b
4.0 6.0
real
img
c
20
AddComplex – step by step
complex a, b, c;
printf(“…");scanf("%lf%lf",&(a.real),&(a.img));printf(“…");scanf("%lf%lf",&(b.real),&(b.img));
c = AddComp(a,b);
printf(“result = %g+%gi\n",c.real,c.img);return 0;
1.0 2.0
real
img
a
3.0 4.0
real
img
b
4.0 6.0
real
img
c
21
Exercise Implement the MultComplex
function – Input - two complex numbers Output – their multiplication Definition: x=a+ib and y=c+id then:
z = xy = (ac-bd)+i(ad+bc)
Write a program that uses the above function to multiply two complex numbers given by the user
22
Solution (MultiplyComplex.c)
complex MultiplyComp(complex a, complex b) {complex c;
c.real = a.real*b.real - a.img*b.img; c.img = a.real*b.img + a.img*b.real;
return c;}
23
More on Structures
Structure members: ordinary variable types, structures, arrays
Passing structures to functions by address A copy of the structure is not created
– just a pointer to the existing structure
24
More on Structures
Structures cannot be compared using the == operator They must be compared member by member Usually this will be done in a separate
function Structures can be copied using the =
operator Member-wise copy
25
Example (Is_In_Circle.c)
int IsInCircle(dot *p_dot, circle *p_circle) { double x_dist,y_dist;
x_dist = p_dot->x - p_circle->center.x; y_dist = p_dot->y - p_circle->center.y;
if((x_dist * x_dist + y_dist * y_dist) <= (p_circle->radius * p_circle->radius))
return 1;
return 0;}
26
Is_in_circle – step by step
printf(“Enter dot\n");scanf("%lf%lf",&d.x,&d.y);printf("Enter circle center\n");scanf("%lf%lf",&c.center.x,&c.center.y);printf("Enter circle radius\n");scanf("%lf",&c.radius);
if (IsInCircle(&d, &c))printf("dot is in circle\n");
elseprintf("dot is out of circle\n");
… …
yx
d (dot)
c (circle)
… …
yx
center (dot) radiu
s…
27
Is_in_circle – step by step
printf(“Enter dot\n");scanf("%lf%lf",&d.x,&d.y);printf("Enter circle center\n");scanf("%lf%lf",&c.center.x,&c.center.y);printf("Enter circle radius\n");scanf("%lf",&c.radius);
if (IsInCircle(&d, &c))printf("dot is in circle\n");
elseprintf("dot is out of circle\n");
… …
yx
d (dot)
c (circle)
… …
yx
center (dot) radiu
s…
28
Is_in_circle – step by step
printf(“Enter dot\n");scanf("%lf%lf",&d.x,&d.y);printf("Enter circle center\n");scanf("%lf%lf",&c.center.x,&c.center.y);printf("Enter circle radius\n");scanf("%lf",&c.radius);
if (IsInCircle(&d, &c))printf("dot is in circle\n");
elseprintf("dot is out of circle\n");
1.0 2.0
yx
d (dot)
c (circle)
… …
yx
center (dot) radiu
s…
29
Is_in_circle – step by step
printf(“Enter dot\n");scanf("%lf%lf",&d.x,&d.y);printf("Enter circle center\n");scanf("%lf%lf",&c.center.x,&c.center.y);printf("Enter circle radius\n");scanf("%lf",&c.radius);
if (IsInCircle(&d, &c))printf("dot is in circle\n");
elseprintf("dot is out of circle\n");
1.0 2.0
yx
d (dot)
c (circle)
… …
yx
center (dot) radiu
s…
30
Is_in_circle – step by step
printf(“Enter dot\n");scanf("%lf%lf",&d.x,&d.y);printf("Enter circle center\n");scanf("%lf%lf",&c.center.x,&c.center.y);printf("Enter circle radius\n");scanf("%lf",&c.radius);
if (IsInCircle(&d, &c))printf("dot is in circle\n");
elseprintf("dot is out of circle\n");
1.0 2.0
yx
d (dot)
c (circle)
0.0 0.0
yx
center (dot) radiu
s…
31
Is_in_circle – step by step
printf(“Enter dot\n");scanf("%lf%lf",&d.x,&d.y);printf("Enter circle center\n");scanf("%lf%lf",&c.center.x,&c.center.y);printf("Enter circle radius\n");scanf("%lf",&c.radius);
if (IsInCircle(&d, &c))printf("dot is in circle\n");
elseprintf("dot is out of circle\n");
1.0 2.0
yx
d (dot)
c (circle)
0.0 0.0
yx
center (dot) radiu
s…
32
Is_in_circle – step by step
printf(“Enter dot\n");scanf("%lf%lf",&d.x,&d.y);printf("Enter circle center\n");scanf("%lf%lf",&c.center.x,&c.center.y);printf("Enter circle radius\n");scanf("%lf",&c.radius);
if (IsInCircle(&d, &c))printf("dot is in circle\n");
elseprintf("dot is out of circle\n");
1.0 2.0
yx
d (dot)
c (circle)
0.0 0.0
yx
center (dot) radiu
s5
33
Is_in_circle – step by step
printf(“Enter dot\n");scanf("%lf%lf",&d.x,&d.y);printf("Enter circle center\n");scanf("%lf%lf",&c.center.x,&c.center.y);printf("Enter circle radius\n");scanf("%lf",&c.radius);
if (IsInCircle(&d, &c))printf("dot is in circle\n");
elseprintf("dot is out of circle\n");
1.0 2.0
yx
d (dot)
c (circle)
0.0 0.0
yx
center (dot) radiu
s5
34
Is_in_circle – step by stepint IsInCircle(dot *p_dot, circle *p_circle){ double x_dist,y_dist;
x_dist = p_dot->x - p_circle->center.x; y_dist = p_dot->y - p_circle->center.y; if (x_dist*x_dist + y_dist*y_dist <= p_circle->radius*p_circle-
>radius) return 1;
return 0;}
1.0 2.0
yx
(dot)
(circle)
0.0 0.0
yx
center (dot) radiu
s5
x_dist
y_dist… …
p_circle
p_dot1024756
35
Is_in_circle – step by stepint IsInCircle(dot *p_dot, circle *p_circle){ double x_dist,y_dist;
x_dist = p_dot->x - p_circle->center.x; y_dist = p_dot->y - p_circle->center.y; if (x_dist*x_dist + y_dist*y_dist <= p_circle->radius*p_circle-
>radius) return 1;
return 0;}
1.0 2.0
yx
(dot)
(circle)
0.0 0.0
yx
center (dot) radiu
s5
x_dist
y_dist1.0 …
p_circle
p_dot1024756
36
Is_in_circle – step by stepint IsInCircle(dot *p_dot, circle *p_circle){ double x_dist,y_dist;
x_dist = p_dot->x - p_circle->center.x; y_dist = p_dot->y - p_circle->center.y; if (x_dist*x_dist + y_dist*y_dist <= p_circle->radius*p_circle-
>radius) return 1;
return 0;}
1.0 2.0
yx
(dot)
(circle)
0.0 0.0
yx
center (dot) radiu
s5
x_dist
y_dist1.0 2.0
p_circle
p_dot1024756
37
Is_in_circle – step by stepint IsInCircle(dot *p_dot, circle *p_circle){ double x_dist,y_dist;
x_dist = p_dot->x - p_circle->center.x; y_dist = p_dot->y - p_circle->center.y; if (x_dist*x_dist + y_dist*y_dist <= p_circle->radius*p_circle-
>radius) return 1;
return 0;}
1.0 2.0
yx
(dot)
(circle)
0.0 0.0
yx
center (dot) radiu
s5
x_dist
y_dist1.0 2.0
p_circle
p_dot1024756
38
Is_in_circle – step by stepint IsInCircle(dot *p_dot, circle *p_circle){ double x_dist,y_dist;
x_dist = p_dot->x - p_circle->center.x; y_dist = p_dot->y - p_circle->center.y; if (x_dist*x_dist + y_dist*y_dist <= p_circle->radius*p_circle-
>radius) return 1;
return 0;}
1.0 2.0
yx
(dot)
(circle)
0.0 0.0
yx
center (dot) radiu
s5
x_dist
y_dist1.0 2.0
p_circle
p_dot1024756
39
Is_in_circle – step by step
printf(“Enter dot\n");scanf("%lf%lf",&d.x,&d.y);printf("Enter circle center\n");scanf("%lf%lf",&c.center.x,&c.center.y);printf("Enter circle radius\n");scanf("%lf",&c.radius);
if (IsInCircle(&d, &c))printf("dot is in circle\n");
elseprintf("dot is out of circle\n");
1.0 2.0
yx
d (dot)
c (circle)
0.0 0.0
yx
center (dot) radiu
s5
40
Exercise
Write a struct that represents a date (day, month, year)
Write a function that increments the datevoid IncDate(Date *d);
For example – 31.12.05 -> 1.1.06
41
Solution
IncDate.c
42
Structures containing arrays A structure member that is an array
does not ‘behave’ like an ordinary array ‘=‘: the array is copied element by
element It is not the address that gets copied! For example - array_member.c
Reminder – ordinary arrays can’t be copied simply by using the ‘=‘ operator They must be copied using a loop
43
Structures containing arrays Same behavior when passing the
structure to a function Changing the array inside the function won’t
change it in the calling function Reminder – when passing an ordinary
array to a function, all that gets passed is the address of its first element Hence every change to the array within the
function, changes the array in the calling function
44
Pointers are another matter
If the member is a pointer all that gets copied is the pointer (the address) itself For example, pointer_member.c
Make sure that you understand what you do!
45
Dynamic Memory Allocation
46
Dynamic Memory Allocation: Motivation
Array variables have fixed size (e.g.: int – 4 bytes, char – 1 byte)
This can’t be changed after compilation
It is not always known how many elements we will need in runtime
We would like to be able to dynamically allocate memory
47
The malloc function
void *malloc(unsigned int n);
The function malloc is used to dynamically allocate n bytes
malloc returns a pointer to the allocated area on success, NULL on failure
48
The malloc function
void *malloc(unsigned int n);
We should always check whether memory was successfully allocated
Remember to #include <stdlib.h> Allocated memory must be freed
(later)
49
Usage Example
int n, *p;printf("How many numbers do you want to
enter?\n");scanf("%d",&n);
p = (int *)malloc(n*sizeof(int));
if(p == NULL) {printf("Memory allocation failed!\n");return 1;
}
free(p);
50
Why casting?
The casting in p=(int *) malloc(n*sizeof (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.
51
What is this ‘sizeof’ ?
The sizeof operator gets a variable or a type as an input and outputs its size in bytes:
double x; s1=sizeof(x); /* s1 is 8 */ s2=sizeof(int) /* s2 is 4 */
52
Free the allocated memory segment
void free(void *ptr);
We use free(p) to free the allocated memory pointed to by p
If p doesn’t point to an area allocated by malloc, a run-time error occurs
53
Free the allocated memory segment
void free(void *ptr);
Always remember to free the allocated memory once you don’t need it
Otherwise, you may run out of memory – a common bug that is hard to detect
54
Example
dynamic_reverse_array.c
55
Example (dynamic_reverse_array.c)
int i, n, *p;printf("How many numbers do you want to enter?\n");scanf("%d",&n);
p = (int *)malloc(n*sizeof(int));if(p == NULL) {
printf("Memory allocation failed!\n");return 1;
}printf("Please enter numbers now:\n");for(i=0; i<n; i++)
scanf("%d", &p[i]);
printf("The numbers in reverse order are - \n");for(i=n-1; i>=0; i--) printf("%d ",p[i]);free(p);
56
Allocating memory within a function
Dynamic allocation of memory is not deleted when we leave the scope / exit a function
This is why we need to free it Now we are able to allocate
memory within a function and use it outside
57
Example (another_strcpy.c)
char *another_strcpy(char *src) {char *dst; int len, i;
len=strlen(src);dst=(char*)malloc(sizeof(char)*(len+1));if(dst == NULL) {
printf("Memory allocation failed!\n");
return NULL;}
for(i=0;i<=len;i++)dst[i] = src[i];
return dst;}
58
Exercise (@ home) Implement the function my_strcat –
Input – two strings, s1 and s2 Output – a pointer to a dynamically allocated
concatenation (‘shirshur’) For example: The concatenation of “hello_”
and “world!” is the string “hello_world!” Write a program that accepts two strings
from the user and prints their concatenation Assume input strings are no longer than a
100 chars
59
Solution
my_strcat.c (my_strcat2.c)
60
What’s wrong with this?char *my_strcat(char *str1, char *str2){
int len;char result[500]; /* Let’s assume this is large enough */
len = strlen(str1);
strcpy(result, str1);strcpy(result+len, str2);
return result;}
61
Exiting the program
void exit(int status); Sometimes an error occurs and we want
the program to immediately exit The exit function closes all open files,
frees all allocated memory, and exits the program
Equivalent to calling ‘return’ within main Remember to #include <stdlib.h> See strcpy_with_exit.c