Download presentation
Presentation is loading. Please wait.
1
Programming Structures and Dynamic Allocation
2
Dynamic 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
3
The Memory Two Parts: 1. Stack Memory is allocated when entering a function Deallocation when the function terminates 2. Heap Programmer control allocation and deallocation
4
Memory Management stdlib.h Two operations for memory management 1. Allocation void* malloc(…); 2. Deallocation void free(…);
5
The 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
6
The free Function void free(void *ptr); Use free(p) to deallocate memory pointed by p If p doesn’t 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
7
Example 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); return 0; }
8
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.
9
What 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 */
10
Example char name[25]; char* 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"); 25 4 True
11
Returning 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; }
12
Exercise Implement the function char* 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
13
Solution 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; }
14
What’s Wrong Here? char* my_strcat(const char *s1, const char *s2) { int len; char result[500]; /* assume this is enough */ strcpy(result, s1); strcpy(result + strlen(s1), s2); return result; }
15
Pitfalls 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;
16
Structures 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?
17
Examples Book Title, Authors, ISBN, Publisher Bank Account Owners, Balance, Credit Car Make, Model, Year
18
A convenient way of grouping several pieces of related information together. A collection of variables under a single name. Structures - User Defined Types
19
Structures - Example struct point { double x; double y; }; struct rectangle { struct point low_left; struct point up_right; }; struct student { char id[10]; char* name; int avg_grade; }; struct point { double x, y; };
20
Defining a struct struct struct-name { type field-name1; type field-name2; type field-name3;... };
21
Example - Complex Numbers Structure declaration Variable definition Define variables of type complex struct complex { double real, img; }; struct complex c1, c2;
22
Field Access Use the. (dot) operator to access a field in a structure. If comp is of type complex then to access the real part we write comp.real and to access the imaginary part we write comp.img
23
Example Printing a complex number printf("%g + %gi", comp.real, comp.img); Input from the user scanf("%lf", &comp.real);
24
Typdef Introduce synonyms for types typedef int Boolean; typedef char* String; Boolean b; String str = "Text";
25
Typdef and Structs Instead of writing struct complex everywhere we can create a shorter synonym using typedef. typdef struct complex Complex Then use it Complex c1, c2;
26
We can combine the typdef with the structure declaration: typedef struct complex { int real; int img; } Complex; This is the common way to define new types Typedef Even Shorter
27
Structures 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
28
Structures and Functions - Example Complex make_complex(double real, double img) { Complex temp; temp.real = real; temp.img = img; return temp; } Complex add_complex(Complex c1, Complex c2) { return make_comlex(c1.real + c2.real, c1.img + c2.img); }
29
add_complex – step by step int main(void) { Complex a, b, sum; printf("…"); scanf("%lf%lf", &(a.real), &(a.img)); printf("…"); scanf("%lf%lf", &(b.real), &(b.img)); sum = add_complex(a, b); printf("result = %g+%gi\n", sum.real, sum.img); return 0; } …… realimg a …… realimg b …… realimg sum
30
add_complex – step by step int main(void) { Complex a, b, sum; printf("…"); scanf("%lf%lf", &(a.real), &(a.img)); printf("…"); scanf("%lf%lf", &(b.real), &(b.img)); sum = add_complex(a, b); printf("result = %g+%gi\n", sum.real, sum.img); return 0; } …… realimg a …… realimg b …… realimg sum
31
add_complex – step by step int main(void) { Complex a, b, sum; printf("…"); scanf("%lf%lf", &(a.real), &(a.img)); printf("…"); scanf("%lf%lf", &(b.real), &(b.img)); sum = add_complex(a, b); printf("result = %g+%gi\n", sum.real, sum.img); return 0; } 1.02.0 realimg a …… realimg b …… realimg sum
32
add_complex – step by step int main(void) { Complex a, b, sum; printf("…"); scanf("%lf%lf", &(a.real), &(a.img)); printf("…"); scanf("%lf%lf", &(b.real), &(b.img)); sum = add_complex(a, b); printf("result = %g+%gi\n", sum.real, sum.img); return 0; } 1.02.0 realimg a …… realimg b …… realimg sum
33
add_complex – step by step int main(void) { Complex a, b, sum; printf("…"); scanf("%lf%lf", &(a.real), &(a.img)); printf("…"); scanf("%lf%lf", &(b.real), &(b.img)); sum = add_complex(a, b); printf("result = %g+%gi\n", sum.real, sum.img); return 0; } 1.02.0 realimg a 3.24.5 realimg b …… realimg sum
34
add_complex – step by step int main(void) { Complex a, b, sum; printf("…"); scanf("%lf%lf", &(a.real), &(a.img)); printf("…"); scanf("%lf%lf", &(b.real), &(b.img)); sum = add_complex(a, b); printf("result = %g+%gi\n", sum.real, sum.img); return 0; } 1.02.0 realimg a 3.24.5 realimg b …… realimg sum
35
add_complex – step by step Complex add_complex(Complex x, Complex y) { Complex sum; sum.real = x.real + y.real; sum.img = x.img + y.img; return sum; } 1.02.0 realimg x 3.2 4.5 realimg y …… realimg sum
36
add_complex – step by step Complex add_complex(Complex x, Complex y) { Complex sum; sum.real = x.real + y.real; sum.img = x.img + y.img; return sum; } 1.02.0 realimg x 3.24.5 realimg y …6.5 realimg sum
37
add_complex – step by step Complex add_complex(Complex x, Complex y) { Complex sum; sum.real = x.real + y.real; sum.img = x.img + y.img; return sum; } 1.02.0 realimg x 3.24.5 realimg y 4.26.5 realimg sum
38
add_complex – step by step Complex add_complex(Complex x, Complex y) { Complex sum; sum.real = x.real + y.real; sum.img = x.img + y.img; return sum; } 1.02.0 realimg x 3.24.5 realimg y 4.26.5 realimg sum
39
add_complex – step by step int main(void) { Complex a, b, sum; printf("…"); scanf("%lf%lf", &(a.real), &(a.img)); printf("…"); scanf("%lf%lf", &(b.real), &(b.img)); sum = add_complex(a, b); printf(“result = %g+%gi\n", sum.real, sum.img); return 0; } 1.02.0 realimg a 3.24.5 realimg b 4.26.5 realimg sum
40
add_complex – step by step int main(void) { Complex a, b, sum; printf("…"); scanf("%lf%lf", &(a.real), &(a.img)); printf("…"); scanf("%lf%lf", &(b.real), &(b.img)); sum = add_complex(a, b); printf(“result = %g+%gi\n", sum.real, sum.img); return 0; } 1.02.0 realimg a 3.24.5 realimg b 4.26.5 realimg sum
41
add_complex – step by step int main(void) { Complex a, b, sum; printf("…"); scanf("%lf%lf", &(a.real), &(a.img)); printf("…"); scanf("%lf%lf", &(b.real), &(b.img)); sum = add_complex(a, b); printf(“result = %g+%gi\n", sum.real, sum.img); return 0; } 1.02.0 realimg a 3.24.5 realimg b 4.26.5 realimg sum
42
Assignment Structures can be assigned (copied) using the assignment operator “=” Bitwise copy – copying the content of one structure’s memory onto another c1 = add_complex(…); 10010011 10101010 01010101 01011101 01110101 00000000 00000000 00000000 00000000 00000000 c1c2 10010011 10101010 01010101 01011101 01110101
43
Arrays in Structs The entire array is part of the structure When passing the struct to a function (by value) Changing the array field won’t change the original array
44
Pointers 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
45
Comparison Structures cannot be compared using the equality operator “==” They must be compared member by member Usually this will be done in a separate function is_equal_complex(Complex c1, Complex c2) { return (c1.real == c2.real) && (c1.img == c2.img); }
46
Exercise Implement a multiply_complex function: Complex multiply_complex(Complex x, Complex y); Note: if x = a + b i and y = c + d i then: z = xy = (ac - bd) + (ad + bc) i Write a program that uses the above function to multiply two complex numbers given by the user
47
Solution Complex make_complex(double real, double img) { Complex temp; temp.real = real; temp.img = img; return temp; } Complex multiply_complex(Complex a, Complex b) { return make_complex(a.real * b.real - a.img * b.img, a.real * b.img + a.img * b.real); }
48
Pointers to Structures Same as with other types Pointer definition structure-name * variable-name; Complex* comptr; Complex c, *cptr; cptr = &c; defines a complex and a pointer to a complex assign the address of the complex variable to the complex pointer
49
To access the fields we can write: (*pcomp).real (*pcomp).img Complex comp; Complex *pcomp = ∁ Accessing Fields Using Pointers
50
Alternative Syntax Pointer to structures are extremely common Alternative notation as a shorthand p →member-of-structure → is minus sign followed by > Example pcomp→real pcomp→img
51
Example typdef struct point { double x, y; } Point; typdef struct rect { Point pt1, pt2; } Rect; Rect r, *rp = &r; r.pt1.x (*rp).pt1.x rp->pt1.x equivalent
52
Example typedef struct point { double x; double y; } Point; typedef struct circle { Point center; double radius; } Circle;
53
Example int is_in_circle(Point *p, Circle *c) { double x_dist, y_dist; x_dist = p->x - c->center.x; y_dist = p->y - c->center.y; return (x_dist * x_dist + y_dist * y_dist radius * c->radius); } A point is in a circle if its distance from the center is smaller than the radius.
54
Exit 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
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.