520 likes | 584 Views
Learn how to dynamically allocate memory, free allocated memory, implement functions, manipulate structures, access members, and create complex data types in C programming. This exercise covers dynamic allocation, structures, malloc, free, casting, concatenation, and more.
E N D
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(unsignedint 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 becausemallocreturnsvoid * : 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 usefree(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: structcomplex num1, num2, num3;
Access structure members • If A is a variable of some structure type with a member named x, then A.xis 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 structcomplex_t { int real; int img; } complex; • Now the program has a new variable type - “complex”. • This way we don’t have to write “structcomplex” every time! • For example, we can define two complex numbers in the following line: complex num1, num2;
Examples AddComplex.c IncDate.c
c a b img img img real real real … … … … … … 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;
c a b img img img real real real … … … … … … 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;
c a b img img img real real real 1.0 … … … … 2.0 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;
c a b img img img real real real 1.0 … … … … 2.0 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;
c a b img img img real real real 1.0 3.0 … … 4.0 2.0 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;
c a b img img img real real real 1.0 3.0 … … 4.0 2.0 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;
z x y img img img real real real 1.0 3.0 … … 4.0 2.0 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; }
z x y img img img real real real 1.0 3.0 … 6.0 4.0 2.0 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; }
z x y img img img real real real 1.0 3.0 4.0 6.0 4.0 2.0 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; }
z x y img img img real real real 1.0 3.0 4.0 6.0 4.0 2.0 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; }
c a b img img img real real real 1.0 3.0 4.0 6.0 4.0 2.0 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;
c a b img img img real real real 1.0 3.0 4.0 6.0 4.0 2.0 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;
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
d (dot) x y … … c (circle) center (dot) radius x y … … … 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"); else printf("dot is out of circle\n");
d (dot) x y … … c (circle) center (dot) radius x y … … … 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"); else printf("dot is out of circle\n");
d (dot) x y 1.0 2.0 c (circle) center (dot) radius x y … … … 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"); else printf("dot is out of circle\n");
d (dot) x y 1.0 2.0 c (circle) center (dot) radius x y … … … 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"); else printf("dot is out of circle\n");
d (dot) x y 1.0 2.0 c (circle) center (dot) radius x y … 0.0 0.0 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"); else printf("dot is out of circle\n");
d (dot) x y 1.0 2.0 c (circle) center (dot) radius x y … 0.0 0.0 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"); else printf("dot is out of circle\n");
d (dot) x y 1.0 2.0 c (circle) center (dot) radius x y 5 0.0 0.0 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"); else printf("dot is out of circle\n");
d (dot) x y 1.0 2.0 c (circle) center (dot) radius x y 5 0.0 0.0 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"); else printf("dot is out of circle\n");
(dot) x y 1.0 2.0 (circle) center (dot) radius x y 5 0.0 0.0 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; } x_dist y_dist … … p_dot p_circle 756 1024
(dot) x y 1.0 2.0 (circle) center (dot) radius x y 5 0.0 0.0 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; } x_dist y_dist 1.0 … p_dot p_circle 756 1024
(dot) x y 1.0 2.0 (circle) center (dot) radius x y 5 0.0 0.0 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; } x_dist y_dist 1.0 2.0 p_dot p_circle 756 1024
(dot) x y 1.0 2.0 (circle) center (dot) radius x y 5 0.0 0.0 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; } x_dist y_dist 1.0 2.0 p_dot p_circle 756 1024
(dot) x y 1.0 2.0 (circle) center (dot) radius x y 5 0.0 0.0 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; } x_dist y_dist 1.0 2.0 p_dot p_circle 756 1024
d (dot) x y 1.0 2.0 c (circle) center (dot) radius x y 5 0.0 0.0 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"); else printf("dot is out of circle\n");
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