Presentation is loading. Please wait.

Presentation is loading. Please wait.

17. ADVANCED USES OF POINTERS. Dynamic Storage Allocation Many programs require dynamic storage allocation: the ability to allocate storage as needed.

Similar presentations


Presentation on theme: "17. ADVANCED USES OF POINTERS. Dynamic Storage Allocation Many programs require dynamic storage allocation: the ability to allocate storage as needed."— Presentation transcript:

1 17. ADVANCED USES OF POINTERS

2 Dynamic Storage Allocation Many programs require dynamic storage allocation: the ability to allocate storage as needed during program execution. Dynamically allocated storage may be used for any kind of data object. The objects most commonly allocated are: Arrays Strings Structures Dynamically allocated structures can be linked together to form lists, trees, and other data structures.

3 The malloc Function The most important storage allocation function is named malloc. When called, malloc allocates a block of size bytes and returns a pointer to it: void *malloc(size_t size); malloc returns a “generic” pointer that is capable of pointing at an object of any type. malloc’s return value can be stored in a variable of any pointer type: int *pi; pi = malloc(sizeof(int)); /* allocate memory for an int */ For portability, it is best to use sizeof when calling malloc. Memory allocated by malloc is not cleared.

4 The Null Pointer When malloc cannot locate a memory block of the requested size, it returns a null pointer. The macro NULL represents the null pointer. It is defined in,,,,, and ; one of these must be included in any program that uses NULL. NULL actually stands for the value 0: #define NULL 0 To avoid confusion with the integer 0, it’s usually best to use NULL instead of 0 to represent the null pointer.

5 The Null Pointer Since NULL is equivalent to 0, it tests false in if, while, do, and for statements: int *p; … if (p) … /* true if p is not NULL */ It is illegal to apply the indirection operator to a null pointer: p = NULL; i = *p; /* illegal */

6 Dynamically Allocated Strings malloc is often used to dynamically allocate space for strings. malloc is especially useful to allocate space for the result of a string operation: char *result; result = malloc(strlen(s1) + strlen(s2) + 1); strcpy(result, s1); strcat(result, s2); Warning: When using malloc to allocate space for a string, don’t forget to include room for the null character.

7 Dynamically Allocated Arrays An array can be dynamically allocated by a call of the calloc function.calloc is similar to malloc, but allocates space for an array with nmemb elements, each of which is size bytes long: void *calloc(size_t nmemb, size_t size); The block of memory allocated by calloc is cleared (set to 0 bits).

8 Dynamically Allocated Arrays Example: int *a, size, i; printf("Enter array size: "); scanf("%d", &size); a = calloc(size, sizeof(int)); printf("Enter array elements: "); for (i = 0; i < size; i++) scanf("%d", &a[i]); Warning: A program that uses malloc or calloc must include the following header file: #include If this file is not included, calloc and malloc would be assumed to return int values, causing unpredictable effects.

9 The free Function When a block of memory obtained by calling malloc or calloc is no longer referenced by a pointer, it is said to be garbage. In the following example, the memory pointed to by p becomes garbage when p is assigned a new value: int *p, *q; p = malloc(sizeof(int)); q = malloc(sizeof(int)); p = q; Garbage should be avoided; we need to “recycle” memory instead.

10 The free Function When a block of memory is no longer needed, it can be released by calling the free function: int *p, *q; p = malloc(sizeof(int)); q = malloc(sizeof(int)); free(p); p = q; Warning: Watch for “dangling pointers” left behind by a call of free: int *p, *q; p = malloc(sizeof(int)); q = p; free(p); *q = 0; /* error */

11 Linked Lists Dynamic storage allocation is useful for building lists, trees, graphs, and other linked structures. A linked structure consists of a collection of nodes. Each node contains one or more pointers to other nodes. In C, a node is represented by a structure. The simplest linked structure is the linked list, which consists of a chain of nodes, with each node pointing to the next node in the chain. A node in a linked list might have the following definition: struct node { int data; struct node *next; }; The use of a structure tag is mandatory, since the node structure contains a reference to itself.

12 Linked Lists An ordinary pointer variable points to the first node in the list; to indicate that the list is empty, the variable can be assigned NULL: struct node *first = NULL;

13 The Right Arrow Operator Nodes can be created by calling malloc: struct node *temp; temp = malloc(sizeof(struct node)); The. operator can be used to select the data member in the node that temp points to: (*temp).data = n; Because pointers often point to structures, C provides a special notation (the right arrow selection operator) for selecting members of these structures: temp->data = n;

14 Example: Inserting into a Linked List The following statements will create a node containing n, then insert it at the beginning of the list pointed to by first: struct node *temp; temp = malloc(sizeof(struct node)); temp->data = n; temp->next = first; first = temp;

15 Example: Inserting into a Linked List The following example creates a linked list containing numbers entered by the user: struct node *first = NULL, *temp; int n; printf("Enter a series of numbers (enter 0 to stop): "); scanf("%d", &n); while (n != 0) { temp = malloc(sizeof(struct node)); temp->data = n; temp->next = first; first = temp; scanf("%d", &n); } The numbers will appear in the list in the reverse of the order in which they were entered.

16 Example: Searching a Linked List The following statement searches a list for an integer n: for (temp = first; temp != NULL; temp = temp->next) if (temp->data == n) … /* found n */

17 Example: Deleting from a Linked List The following statements will delete the first node containing n from the list pointed to by first, assuming that n is present in the list: struct node *p, *q; for (p = first, q = NULL; p != NULL && p->data != n; q = p, p = p->next); if (q == NULL) first = first->next; /* n is at the beginning */ else q->next = p->next; /* n is not at the beginning */ free(p);

18 Functions Passed as Arguments C does not allow a function to be passed as an argument to another function. However, a pointer to a function can be passed: int find_zero(int (*f)(int)); int poly(int i); int main(void) { printf("Answer: %d\n", find_zero(poly)); return 0; } int find_zero(int (*f)(int)) { int n = 0; while ((*f)(n)) n++; /* or while (f(n)) n++; */ return n; } int poly(int i) { return i * i + i - 12; }

19 Functions Passed as Arguments Pointers to functions can be used in numerous other ways. For example: A function can return a pointer to a function. A variable can store a pointer to a function. An array may contain pointers to functions.

20 The qsort Function Certain functions in the C standard library require a function pointer as a parameter. One of the most commonly used is qsort, a general- purpose algorithm capable of sorting any array. The following declaration for qsort appears in : void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *)); base is a pointer to the first element in the array. nmemb is the number of elements in the array. size is the size of each array element. compar is a pointer to a function that compares two array elements.

21 The qsort Function When given two pointers p and q to array elements, compar must return a number that is Negative if *p is “less than” *q. Zero if *p is “equal to” *q. Positive if *p is “greater than” *q.


Download ppt "17. ADVANCED USES OF POINTERS. Dynamic Storage Allocation Many programs require dynamic storage allocation: the ability to allocate storage as needed."

Similar presentations


Ads by Google