Post on 02-Jan-2016
description
Exercise 11
Dynamic allocation and structures
Dynamic Allocation
Array variables have fixed size, used to store a fixed and known amount of variables – known at the time of compilation
This size can’t be changed after compilation However, we don’t always know in advance
how much space we would need for an array or a variable
We would like to be able to dynamically allocate memory
The malloc function
void * malloc(unsigned int nBytes);
The function 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 <stdlib.h>
Example
dynamic_reverse_array.c
Why casting?
The casting in y = (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.
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 */
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
Always remember to free the allocated memory once you don’t need it anymore
Otherwise, you may run out of memory before you know it!
Another example
another_strcpy.c
Exercise
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
Solution
my_strcat.c (my_strcat2.c)
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;}
Structures
Often we want to be able to manipulate ‘logical entities’ as a whole For example, complex numbers, dates,
student records, etc’ Each of these must be composed of more
than one variable, but are logically units
Structures
A struct (short for structure) is a collection of variables of different types, gathered into one super-variable
It is used to define more complex data types
Variables in a struct are called members or fields
Example – complex numbers.
The following is the definition of a new ‘variable’ of type complex number:
struct complex { int real; int img; };
Once we define a structure, we can treat it as any type. In a program, we can then write:
struct complex num1, num2, num3;
Access structure members
If A is a variable of some structure type with a member named x, then A.x is that member of A struct complex C;
C.real = 0;
If pA is a pointer to a structure with a member x, then pA->x is that member of the variable pointed by pA. This is simply shorthand for (*pA).x
struct complex *pc = &C;
pc->real = 1;
A more convenient usage with typedef
An alternative definition:typedef struct complex_t {
int real; int img; } complex;
Now the program has a new variable type - “complex”. This way we don’t have to write “struct complex” every
time! For example, we can define two complex numbers in the
following line:complex num1, num2;
Examples
AddComplex.c
IncDate.c
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
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
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
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
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
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
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
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
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
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
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
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
Miscellaneous structure trivia
Structure members may be ordinary variable types, but also other structures and even arrays!
Structures can therefore be rather large and take up a lot of space
Many times we prefer to pass structures to functions by address, and not by value Thus a new copy of the structure is not created –
just a pointer to the existing structure
More trivia
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
Example
Is_In_Circle.c
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…
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…
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…
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…
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…
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…
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
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
Is_in_circle – step by step
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;}
1.0 2.0
yx
(dot)
(circle)
0.0 0.0
yx
center (dot) radiu
s5
x_dist
y_dist… …
p_circle
p_dot1024756
Is_in_circle – step by step
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;}
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
Is_in_circle – step by step
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;}
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
Is_in_circle – step by step
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;}
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
Is_in_circle – step by step
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;}
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
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
Exercise
Implement the MultComplex function: Input – two complex numbers Output – their multiplication Note: if 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
Solution
MultiplyComplex.c
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
Structures containing arrays
A structure member that is an array does not ‘behave’ like an ordinary array
When copying a structure that contains a member which is an array, the array is copied element by element Not just the address 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
Structures containing arrays
When passing the structure to a function by value Changing the array field 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
Pointers are another matter
If the member is a pointer, for example to a dynamically allocated array, all that gets copied is the pointer (the address) itself For example, pointer_member.c
Hence, we should take extra care when manipulating structures that contain pointers