Advanced Uses of Pointers
Exercises
Question 17.1
Having to check the return value of malloc (or any other memory allocation function) each time we call it can be an annoyance. Write a function named my_malloc that serves as a "wrapper" for malloc. When we call my_malloc and ask it to allocate n bytes, it in turn calls malloc, tests to make sure that malloc doesn't return a null pointer, and then returns the pointer from malloc. Have my_malloc print an error message and terminate the program if malloc returns a null pointer.
- Program
- Output
#include <stdio.h>
#include <stdlib.h>
#define MALLOC_ERR(size_t_bytes) \
printf("[ERROR] Failed to allocate %zu bytes of memory on\nfile: %s\nline: %d\n", size_t_bytes, __FILE__, __LINE__)
/*
* my_malloc: Returns a pointer/address that can store bytes byte of data
Enter the size of the array to store the integer elements: 5 Enter element 0: 1 Enter element 1: 2 Enter element 2: 3 Enter element 3: 4 Enter element 4: 5 The array contains the following elements: Element 0: 1 Element 1: 2 Element 2: 3 Element 3: 4 Element 4: 5
Question 17.2
Write a function named duplicate that uses dynamic storage allocation to create a copy of a string. For example, the call
p = duplicate(str);
would allocate space for a string of the same length as str, copy the contents of str into the new string and return a pointer to it. Have duplicate return a null pointer if the memory allocation fails.
- Program
- Output
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define STR_SIZE 100
/*
* duplicate: Returns a memory address that allocates the number of bytes
Enter a sentence to be duplicated: Hey I am Pranav! [LOG] The size of the string is: 17 The duplicated string/sentence is: Hey I am Pranav!
Question 17.3
Write the following function:
int *create_array(int n, int initial_value);
The function should return a pointer to a dynamically allocated int array with n members, each of which is initialized to initial_value. The return value should be NULL if the array can't be allocated.
- Program
- Output
#include <stdio.h>
#include <stdlib.h>
/*
* create_array: Creates an array of n elements, each element is initialized
* with the value initial_value. If the cannot be created, returns
* NULL.
*/
int *create_array (int n, int initial_value);
Enter the array size and the initial value: 5 1 [SUCCESS] Created an Array of size 5. Element 0 has the value: 1 Element 1 has the value: 1 Element 2 has the value: 1 Element 3 has the value: 1 Element 4 has the value: 1
Question 17.4
Suppose that the following declarations are in effect:
struct point { int x, y; };
struct rectangle { struct point upper_left, lower_right; };
struct rectangle *p;
Assume that we want p to point to a rectangle structure whose upper left corner is at (10, 25) and whose lower right corner is at (20. 15). Write a series of statements that allocate such a structure and initialize it as indicated.
- Program
- Output
#include <stdio.h>
#include <stdlib.h>
struct point { int x, y; };
struct rectangle { struct point upper_left, lower_right; };
/*
* initialize_rectangle: Returns a pointer to a rectangle structure which has the
* member upper_left and lower_right initialized as provided
Enter the coordinates for the upper left corner (format: x, y): 0, 10 Enter the coordinates for the lower right corner (format: x, y): 8, 0 The rectangle has the following property: Upper Left Coordinate : 0, 10 Lower Right Coordinates : 8, 0
Question 17.5
Suppose that f and p are declared as follows:
struct {
union {
char a, b;
int c;
} d;
int e[5];
} f, *p = &f;
Which of the following statements are legal?
p->b = ' 'p->e[3] = 10;(*p).d.a = '*';p->d->c = 20;
- Answer
- Output
- Program
Based on the provided structre, I'd say that:
- is not legal as it is accessing member
bof uniondwithout specifying. The correct and legal way would probably bep->d.b = ' '; - is probably legal as it would go as:
p->*(e+3) = 10;which is similar to accesing a integer value. - is legal as
(*p)will "indirect" the pointerp, making it act like a normal structure variable. We can then use the dot (.) operator to access the members without any issue. - is probably not legal as the arrow operator (
->) is used to access member of a pointer variable. Whilepis a pointer variable,d- which is a union - is not a pointer to the union. Sincedis not a pointer, we cannot use the arrow operator to access the member c of the union. The correct way would be:p->d.c = 20;
After checking the ouput, it was as expected. But for (b), p->*(e+3) is not correct way to visualize the array operation. It will be roguhly equivalent to: *((p->e) + 3)
Member b of union d of structure pointer p is:
Element 3 of member e of structure pointer p is: 10 Member a of union d of structure pointer p is: * Member c of union d of structure pointer p is: 20
#include <stdio.h>
int main (void) {
struct {
union {
char a, b;
int c;
} d;
Question 17.6
Modify the delete_from_list function so that it uses only one pointer variable instead of two (cur and prev).
- Answer
- Output
- Program
Some constraints need to be defined before we solve the problem:
-
The return type of the function
delete_from_list(sll_delete_nodein the program) must be void because the program utilizes the parameter list for traversing through the linked list. -
The linked list fails to delete the first node, of the list. This means, the latest node added using the
ncommand cannot be removed. The reason for this is, when we send the root pointer to the functionsll_delete_node, we are passing a value - an address of the root node in the linked list - which cannot change the root node's address through the function call. Say that the root node's address is0x1234, then when we pass it as an argument to the function, we are essentially initializing the list pointer with the address0x1234. Now say that the first node needs to be deleted, that means that list = list->next. But this will only change the pointer variable list and not the root pointer variable. This can be solved if the function takes in pointer to a pointer to the typesingly_linked_list_node, i.e. the function parameter should bestruct singly_linked_list_node **list. By doing so, the address of the root pointer variable can be modified, but the issue is that the other nodes cannot be deleted with just one pointer variable as asked by the question.
A simple program that provides the following operations on singly linked list. NOTE: The linked list only has one member: int num. Usage Command 1. Initilize a Singly Linked List (i) 2. Add a new node in the beginning of list (n) 3. Search for a node (s) 4. Delete a node (d) 5. Sort the nodes (o) 6. View all nodes (v) 7. Terminate the program (q) Enter command: i Enter the number to store: 4 A simple program that provides the following operations on singly linked list. NOTE: The linked list only has one member: int num. Usage Command 1. Initilize a Singly Linked List (i) 2. Add a new node in the beginning of list (n) 3. Search for a node (s) 4. Delete a node (d) 5. Sort the nodes (o) 6. View all nodes (v) 7. Terminate the program (q) Enter command: n Enter the number to store: 7 A simple program that provides the following operations on singly linked list. NOTE: The linked list only has one member: int num. Usage Command 1. Initilize a Singly Linked List (i) 2. Add a new node in the beginning of list (n) 3. Search for a node (s) 4. Delete a node (d) 5. Sort the nodes (o) 6. View all nodes (v) 7. Terminate the program (q) Enter command: n Enter the number to store: 2 A simple program that provides the following operations on singly linked list. NOTE: The linked list only has one member: int num. Usage Command 1. Initilize a Singly Linked List (i) 2. Add a new node in the beginning of list (n) 3. Search for a node (s) 4. Delete a node (d) 5. Sort the nodes (o) 6. View all nodes (v) 7. Terminate the program (q) Enter command: v Current Node Addresss Member: num Member: next (node address) 0x3794db00 2 0x3794dae0 0x3794dae0 7 0x3794dac0 0x3794dac0 4 (nil) A simple program that provides the following operations on singly linked list. NOTE: The linked list only has one member: int num. Usage Command 1. Initilize a Singly Linked List (i) 2. Add a new node in the beginning of list (n) 3. Search for a node (s) 4. Delete a node (d) 5. Sort the nodes (o) 6. View all nodes (v) 7. Terminate the program (q) Enter command: o The sorted array is: Address of element 0 and data 2 in list: 0x3794db00 Address of element 1 and data 4 in list: 0x3794dac0 Address of element 2 and data 7 in list: 0x3794dae0 A simple program that provides the following operations on singly linked list. NOTE: The linked list only has one member: int num. Usage Command 1. Initilize a Singly Linked List (i) 2. Add a new node in the beginning of list (n) 3. Search for a node (s) 4. Delete a node (d) 5. Sort the nodes (o) 6. View all nodes (v) 7. Terminate the program (q) Enter command: s Enter the number to search in the list: 4 The node has the following members: int num = 4 struct singly_linked_list_node *next = (nil) A simple program that provides the following operations on singly linked list. NOTE: The linked list only has one member: int num. Usage Command 1. Initilize a Singly Linked List (i) 2. Add a new node in the beginning of list (n) 3. Search for a node (s) 4. Delete a node (d) 5. Sort the nodes (o) 6. View all nodes (v) 7. Terminate the program (q) Enter command: d Enter the number to search in the list: 2 Segmentation fault
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
size_t num_nodes = 0;
typedef unsigned long size_t;
struct singly_linked_list_node {
Question 17.7
The following loop is supposed to delete all nodes from a linked list and release the memory that they occupy. Unfortunately, the loop is incorrect. Explain what's wrong with it and show how to fix the bug.
for (p = first; p != NULL; p = p->next)
free(p);
- Answer
Looking at the code, one of the flaw at the first observation is that, once free is called inside the for loop block, the memory allocated by the pointer p (which is assumed to be a pointer to a structure of members int num and struct linked_list *next) will be released by the program. After the for block is executed, the third expression described in the for statement, i.e. p = p->next is executed. This is illegal as it is trying to access a memory block that is released by the program which will probably send a SIGSEGV (segfault). Since p is being assigned the address pointed to by first, one potential solution can be:
for (; first != NULL;) {
p = first;
first = first->next;
free(p);
}
This program will run as follows:
pwill be assigned the address of pointed to by first.firstwill be assigned the address pointed to by the member next of the structure variable.pwill be freed, without any issue of the program accessing the "illegal" address in the heap.
Question 17.8
Section 15.2 describes a file, stack.c, that provides functions for storing integers in a stack. In that section, the stack was implemented as an array. Modify stack.c so that a stack is now stored as a linked list. Replace the contents and top variables by a single variable that points to the first node in the list (the "top" of the stack). Write the functions in stack.c so that they use this pointer. Remove the is_full function, instead having push return either true (if memory was available to create a node) or false (if not).
- Program
- Output
#include <stdio.h>
#include <stdlib.h>
struct stack_sll {
int content;
struct stack_sll *next;
};
struct stack_sll *push_stack_sll (struct stack_sll *s_list, int content);
A Program to add items in stack that is stored as linked list. Description Command 1. Push Content in Stack a 2. Pop Item From Stack p 3. View Current Stack v 4. Clear the Current Stack c 5. Quit the Program q Enter command: a Enter the content (int) to push into the stack: 1 [SUCCESS] 1 was added to the top of the stack. A Program to add items in stack that is stored as linked list. Description Command 1. Push Content in Stack a 2. Pop Item From Stack p 3. View Current Stack v 4. Clear the Current Stack c 5. Quit the Program q Enter command: a Enter the content (int) to push into the stack: 4 [SUCCESS] 4 was added to the top of the stack. A Program to add items in stack that is stored as linked list. Description Command 1. Push Content in Stack a 2. Pop Item From Stack p 3. View Current Stack v 4. Clear the Current Stack c 5. Quit the Program q Enter command: v Current Address Content Next Address --------------- ----------- ---------------- 0x1dc42ae0 4 0x1dc42ac0 0x1dc42ac0 1 (nil) A Program to add items in stack that is stored as linked list. Description Command 1. Push Content in Stack a 2. Pop Item From Stack p 3. View Current Stack v 4. Clear the Current Stack c 5. Quit the Program q Enter command: p [SUCCESS] The popped Content is: 4 A Program to add items in stack that is stored as linked list. Description Command 1. Push Content in Stack a 2. Pop Item From Stack p 3. View Current Stack v 4. Clear the Current Stack c 5. Quit the Program q Enter command: v Current Address Content Next Address --------------- ----------- ---------------- 0x1dc42ac0 1 (nil) A Program to add items in stack that is stored as linked list. Description Command 1. Push Content in Stack a 2. Pop Item From Stack p 3. View Current Stack v 4. Clear the Current Stack c 5. Quit the Program q Enter command: c [SUCCESS] Stack is cleared. A Program to add items in stack that is stored as linked list. Description Command 1. Push Content in Stack a 2. Pop Item From Stack p 3. View Current Stack v 4. Clear the Current Stack c 5. Quit the Program q Enter command: v [WARN] Stack is currently empty. Push some items to view the contents. A Program to add items in stack that is stored as linked list. Description Command 1. Push Content in Stack a 2. Pop Item From Stack p 3. View Current Stack v 4. Clear the Current Stack c 5. Quit the Program q Enter command: q
Question 17.9
True or false: If x is a structure and a is a member of that structure, then (&x) -> a is the same as x.a. Justify your answer.
- Answer
True. Given that x is a structure variable with a as its member, we can access structure in both ways as described in the question. As &x gives the address of the structure variable, we can use the arrow operator (->) to access the members of a pointer to a structure. We use the dot (.) operator to access the members of a structure variable.
Question 17.10
Modify the print_part function of Section 1672 so that its parameter is a pointer to a part structure. Use the -> operator in your answer.
- Answer
The function definition in #26 of Chapter 16 notes is:
void print_part (struct part p) {
printf("Part number: %d\n", p.number);
printf("Part name: %s\n", p.name);
printf("Quantity on hand: %d\n", p.on_hand);
}
To modify the function parameter such that it takes a pointer to the structure part and print its details, we can do so as:
void print_part (struct part *p) {
printf("Part number: %d\n", p->number);
printf("Part name: %s\n", p->name);
printf("Quantity on hand: %d\n", p->on_hand);
}
To call the function given that a variable of type struct part is defined, we can do so as:
...
struct part p1;
...
print_part(&p1);
Question 17.11
Write the following function:
int count_occurrences(struct node *list, int n);
The list parameter points to a linked list; the function should return the number of times that n appears in this list. Assume that the node structure is the one defined in Section 17.5.
- Program
- Output
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
size_t num_nodes = 0;
typedef unsigned long size_t;
struct singly_linked_list_node {
A simple program that provides the following operations on singly linked list. NOTE: The linked list only has one member: int num. Usage Command 1. Initilize a Singly Linked List (i) 2. Add a new node in the beginning of list (n) 3. Search for a node (s) 4. Delete a node (d) 5. Sort the nodes (o) 6. Count Occurrences (c) 7. View all nodes (v) 8. Terminate the program (q) >> Enter command: i Enter the number to store: n [ERROR] Insufficient Input Field Provided. Enter the number to store: 3 A simple program that provides the following operations on singly linked list. NOTE: The linked list only has one member: int num. Usage Command 1. Initilize a Singly Linked List (i) 2. Add a new node in the beginning of list (n) 3. Search for a node (s) 4. Delete a node (d) 5. Sort the nodes (o) 6. Count Occurrences (c) 7. View all nodes (v) 8. Terminate the program (q) >> Enter command: n Enter the number to store: 7 A simple program that provides the following operations on singly linked list. NOTE: The linked list only has one member: int num. Usage Command 1. Initilize a Singly Linked List (i) 2. Add a new node in the beginning of list (n) 3. Search for a node (s) 4. Delete a node (d) 5. Sort the nodes (o) 6. Count Occurrences (c) 7. View all nodes (v) 8. Terminate the program (q) >> Enter command: n Enter the number to store: 3 A simple program that provides the following operations on singly linked list. NOTE: The linked list only has one member: int num. Usage Command 1. Initilize a Singly Linked List (i) 2. Add a new node in the beginning of list (n) 3. Search for a node (s) 4. Delete a node (d) 5. Sort the nodes (o) 6. Count Occurrences (c) 7. View all nodes (v) 8. Terminate the program (q) >> Enter command: v Current Node Addresss Member: num Member: next (node address) 0x29f20b00 3 0x29f20ae0 0x29f20ae0 7 0x29f20ac0 0x29f20ac0 3 (nil) A simple program that provides the following operations on singly linked list. NOTE: The linked list only has one member: int num. Usage Command 1. Initilize a Singly Linked List (i) 2. Add a new node in the beginning of list (n) 3. Search for a node (s) 4. Delete a node (d) 5. Sort the nodes (o) 6. Count Occurrences (c) 7. View all nodes (v) 8. Terminate the program (q) >> Enter command: c Enter the number to count its occurrences: 3 Total Occurances of 3 in singly linked list: 2 A simple program that provides the following operations on singly linked list. NOTE: The linked list only has one member: int num. Usage Command 1. Initilize a Singly Linked List (i) 2. Add a new node in the beginning of list (n) 3. Search for a node (s) 4. Delete a node (d) 5. Sort the nodes (o) 6. Count Occurrences (c) 7. View all nodes (v) 8. Terminate the program (q) >> Enter command: o The sorted array is: Address of element 0 and data 3 in list: 0x29f20b00 Address of element 1 and data 3 in list: 0x29f20ac0 Address of element 2 and data 7 in list: 0x29f20ae0 A simple program that provides the following operations on singly linked list. NOTE: The linked list only has one member: int num. Usage Command 1. Initilize a Singly Linked List (i) 2. Add a new node in the beginning of list (n) 3. Search for a node (s) 4. Delete a node (d) 5. Sort the nodes (o) 6. Count Occurrences (c) 7. View all nodes (v) 8. Terminate the program (q) >> Enter command: s Enter the number to search in the list: 7 The node has the following members: int num = 7 struct singly_linked_list_node *next = 0x29f20ac0 A simple program that provides the following operations on singly linked list. NOTE: The linked list only has one member: int num. Usage Command 1. Initilize a Singly Linked List (i) 2. Add a new node in the beginning of list (n) 3. Search for a node (s) 4. Delete a node (d) 5. Sort the nodes (o) 6. Count Occurrences (c) 7. View all nodes (v) 8. Terminate the program (q) >> Enter command: d Enter the number to search in the list: 3 A simple program that provides the following operations on singly linked list. NOTE: The linked list only has one member: int num. Usage Command 1. Initilize a Singly Linked List (i) 2. Add a new node in the beginning of list (n) 3. Search for a node (s) 4. Delete a node (d) 5. Sort the nodes (o) 6. Count Occurrences (c) 7. View all nodes (v) 8. Terminate the program (q) >> Enter command: v Current Node Addresss Member: num Member: next (node address) 0x29f20ae0 7 0x29f20ac0 0x29f20ac0 3 (nil) A simple program that provides the following operations on singly linked list. NOTE: The linked list only has one member: int num. Usage Command 1. Initilize a Singly Linked List (i) 2. Add a new node in the beginning of list (n) 3. Search for a node (s) 4. Delete a node (d) 5. Sort the nodes (o) 6. Count Occurrences (c) 7. View all nodes (v) 8. Terminate the program (q) >> Enter command: q
Question 17.12
Write the following function:
struct node *find_last(struct node *list, int n);
The list parameter points to a linked list. The function should return a pointer to the last node that contains n: it should return NULL if n doesn't appear in the list. Assume that the node structure is the one defined in Section 17.5.
- Program
- Output
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
size_t num_nodes = 0;
typedef unsigned long size_t;
struct singly_linked_list_node {
A simple program that provides the following operations on singly linked list. NOTE: The linked list only has one member: int num. Usage Command 1. Initilize a Singly Linked List (i) 2. Add a new node in the beginning of list (n) 3. Search for a node (s) 4. Delete a node (d) 5. Sort the nodes (o) 6. Find last Occurance (l) 7. View all nodes (v) 8. Terminate the program (q) >> Enter command: i Enter the number to store: 3 A simple program that provides the following operations on singly linked list. NOTE: The linked list only has one member: int num. Usage Command 1. Initilize a Singly Linked List (i) 2. Add a new node in the beginning of list (n) 3. Search for a node (s) 4. Delete a node (d) 5. Sort the nodes (o) 6. Find last Occurance (l) 7. View all nodes (v) 8. Terminate the program (q) >> Enter command: n Enter the number to store: 7 A simple program that provides the following operations on singly linked list. NOTE: The linked list only has one member: int num. Usage Command 1. Initilize a Singly Linked List (i) 2. Add a new node in the beginning of list (n) 3. Search for a node (s) 4. Delete a node (d) 5. Sort the nodes (o) 6. Find last Occurance (l) 7. View all nodes (v) 8. Terminate the program (q) >> Enter command: n Enter the number to store: 13 A simple program that provides the following operations on singly linked list. NOTE: The linked list only has one member: int num. Usage Command 1. Initilize a Singly Linked List (i) 2. Add a new node in the beginning of list (n) 3. Search for a node (s) 4. Delete a node (d) 5. Sort the nodes (o) 6. Find last Occurance (l) 7. View all nodes (v) 8. Terminate the program (q) >> Enter command: n Enter the number to store: 2 A simple program that provides the following operations on singly linked list. NOTE: The linked list only has one member: int num. Usage Command 1. Initilize a Singly Linked List (i) 2. Add a new node in the beginning of list (n) 3. Search for a node (s) 4. Delete a node (d) 5. Sort the nodes (o) 6. Find last Occurance (l) 7. View all nodes (v) 8. Terminate the program (q) >> Enter command: s Enter the number to search in the list: 13 The node has the following members: int num = 13 struct singly_linked_list_node *next = 0x34efbae0 A simple program that provides the following operations on singly linked list. NOTE: The linked list only has one member: int num. Usage Command 1. Initilize a Singly Linked List (i) 2. Add a new node in the beginning of list (n) 3. Search for a node (s) 4. Delete a node (d) 5. Sort the nodes (o) 6. Find last Occurance (l) 7. View all nodes (v) 8. Terminate the program (q) >> Enter command: l Enter the number to count its occurrences: 7 [SUCCESS] 7 is found and the address of it's last occurrence in the linked list is: 0x34efbae0 A simple program that provides the following operations on singly linked list. NOTE: The linked list only has one member: int num. Usage Command 1. Initilize a Singly Linked List (i) 2. Add a new node in the beginning of list (n) 3. Search for a node (s) 4. Delete a node (d) 5. Sort the nodes (o) 6. Find last Occurance (l) 7. View all nodes (v) 8. Terminate the program (q) >> Enter command: v Current Node Addresss Member: num Member: next (node address) 0x34efbb20 2 0x34efbb00 0x34efbb00 13 0x34efbae0 0x34efbae0 7 0x34efbac0 0x34efbac0 3 (nil) A simple program that provides the following operations on singly linked list. NOTE: The linked list only has one member: int num. Usage Command 1. Initilize a Singly Linked List (i) 2. Add a new node in the beginning of list (n) 3. Search for a node (s) 4. Delete a node (d) 5. Sort the nodes (o) 6. Find last Occurance (l) 7. View all nodes (v) 8. Terminate the program (q) >> Enter command: o The sorted array is: Address of element 0 and data 2 in list: 0x34efbb20 Address of element 1 and data 3 in list: 0x34efbac0 Address of element 2 and data 7 in list: 0x34efbae0 Address of element 3 and data 13 in list: 0x34efbb00 A simple program that provides the following operations on singly linked list. NOTE: The linked list only has one member: int num. Usage Command 1. Initilize a Singly Linked List (i) 2. Add a new node in the beginning of list (n) 3. Search for a node (s) 4. Delete a node (d) 5. Sort the nodes (o) 6. Find last Occurance (l) 7. View all nodes (v) 8. Terminate the program (q) >> Enter command: d Enter the number to search in the list: 7 A simple program that provides the following operations on singly linked list. NOTE: The linked list only has one member: int num. Usage Command 1. Initilize a Singly Linked List (i) 2. Add a new node in the beginning of list (n) 3. Search for a node (s) 4. Delete a node (d) 5. Sort the nodes (o) 6. Find last Occurance (l) 7. View all nodes (v) 8. Terminate the program (q) >> Enter command: v Current Node Addresss Member: num Member: next (node address) 0x34efbb20 2 0x34efbb00 0x34efbb00 13 0x34efbac0 0x34efbac0 3 (nil) A simple program that provides the following operations on singly linked list. NOTE: The linked list only has one member: int num. Usage Command 1. Initilize a Singly Linked List (i) 2. Add a new node in the beginning of list (n) 3. Search for a node (s) 4. Delete a node (d) 5. Sort the nodes (o) 6. Find last Occurance (l) 7. View all nodes (v) 8. Terminate the program (q) >> Enter command: q
Question 17.13
The following function is supposed to insert a new node into its proper place in an ordered list, returning a pointer to the first node in the modified list. Unfortunately, the function doesn't work correctly in all cases. Explain what's wrong with it and show how to fix it. Assume that the node structure is the one defined in Section 17.5.
struct node *insert_into_ordered_list(struct node *list, struct node *new_node)
{
struct node *cur = list, *prev = NULL;
while (cur->value <= new_node->value) {
prev = cur;
cur = cur->next;
}
prev->next = new_node;
new_node->next = cur;
return list;
}
- Answer
- Output
- Program
Consider a scenario where we call the function with root as the first argument and new_node as the second argument. Say that one function has the memory allocated for the new_node as follows:
void create_new_node (...) {
struct node *new_node;
new_node = malloc(sizeof(struct node));
new_node->value = ...;
struct node *temp;
temp = insert_into_ordered_list(root, new_node);
}
When we call the function in this manner, the function parameter:
- list will hold the pointer to the struct node variable
root, and, new_nodewill hold the pointer to the struct node variablenew_node- defined increate_new_node.
One of the problem of the program is that say that we have a linked list of data: 5, 10. The new value we need to store is 15. What will happen is:
(5 <= 15)istrue, soprevwill now point to address pointed to bycur, andcurwill point to address pointed to bycur->next- which holds the value 10.(10 <= 15)istrue, soprevwill point to node which contains the value 10, andcurwill point to theNULLpointer, assuming that the end of the linked list has theNULLnode.(cur->value <= 15)is evaluated, the expression is not valid as it is trying to access the memory pointed by aNULLpointer, which is aERR_BAD_ACCESS.
To fix this problem, we must have the condition for the while statement as follows:
while (cur != NULL && cur->value <= new_node->value);
Notice that the first expression (cur != NULL) preceeds the given expression (cur->value <= new_node->value). This is done to conform to the short circuiting functionality provided by C. If the first expression is false, lazy evaluation takes places as 0 && anything will result in 0.
This will fix the issue of adding nodes in the list. BUT, this does not solve the problem of adding the node whose value is smaller as compared to other node's value. In such case, the new_node should be added first, which is not the behavior of this program.
To solve this, the following modification needs to be done:
if (prev == NULL) {
new_node->next = cur;
return new_node;
} else {
prev->next = new_node;
new_node->next = cur;
return list;
}
If the new_node contains the value which is lower as compared to other node's value, then the while loop will not run, making prev still point to NULL as it was initialized. Then, the new_node can be modified to act as the first node in the linked list. If not, and the new_node is the one which is to be added between the list or at the end, the else clause will run, and the desired effect is noticed.
A simple program that provides the following operations on singly linked list. NOTE: The linked list only has one member: int num. Usage Command 1. Initilize a Singly Linked List (i) 2. Add a new node in the beginning of list (n) 3. Search for a node (s) 4. Delete a node (d) 5. Sort the nodes (o) 6. Find last Occurance (l) 7. View all nodes (v) 8. Terminate the program (q) >> Enter command: i Enter the number to store: 3 A simple program that provides the following operations on singly linked list. NOTE: The linked list only has one member: int num. Usage Command 1. Initilize a Singly Linked List (i) 2. Add a new node in the beginning of list (n) 3. Search for a node (s) 4. Delete a node (d) 5. Sort the nodes (o) 6. Find last Occurance (l) 7. View all nodes (v) 8. Terminate the program (q) >> Enter command: n Enter the number to store: 7 A simple program that provides the following operations on singly linked list. NOTE: The linked list only has one member: int num. Usage Command 1. Initilize a Singly Linked List (i) 2. Add a new node in the beginning of list (n) 3. Search for a node (s) 4. Delete a node (d) 5. Sort the nodes (o) 6. Find last Occurance (l) 7. View all nodes (v) 8. Terminate the program (q) >> Enter command: n Enter the number to store: 1 A simple program that provides the following operations on singly linked list. NOTE: The linked list only has one member: int num. Usage Command 1. Initilize a Singly Linked List (i) 2. Add a new node in the beginning of list (n) 3. Search for a node (s) 4. Delete a node (d) 5. Sort the nodes (o) 6. Find last Occurance (l) 7. View all nodes (v) 8. Terminate the program (q) >> Enter command: v Current Node Addresss Member: num Member: next (node address) 0x24df8b00 1 0x24df8ac0 0x24df8ac0 3 0x24df8ae0 0x24df8ae0 7 (nil) A simple program that provides the following operations on singly linked list. NOTE: The linked list only has one member: int num. Usage Command 1. Initilize a Singly Linked List (i) 2. Add a new node in the beginning of list (n) 3. Search for a node (s) 4. Delete a node (d) 5. Sort the nodes (o) 6. Find last Occurance (l) 7. View all nodes (v) 8. Terminate the program (q) >> Enter command: s Enter the number to search in the list: 7 The node has the following members: int num = 7 struct singly_linked_list_node *next = (nil) A simple program that provides the following operations on singly linked list. NOTE: The linked list only has one member: int num. Usage Command 1. Initilize a Singly Linked List (i) 2. Add a new node in the beginning of list (n) 3. Search for a node (s) 4. Delete a node (d) 5. Sort the nodes (o) 6. Find last Occurance (l) 7. View all nodes (v) 8. Terminate the program (q) >> Enter command: o The sorted array is: Address of element 0 and data 1 in list: 0x24df8b00 Address of element 1 and data 3 in list: 0x24df8ac0 Address of element 2 and data 7 in list: 0x24df8ae0 A simple program that provides the following operations on singly linked list. NOTE: The linked list only has one member: int num. Usage Command 1. Initilize a Singly Linked List (i) 2. Add a new node in the beginning of list (n) 3. Search for a node (s) 4. Delete a node (d) 5. Sort the nodes (o) 6. Find last Occurance (l) 7. View all nodes (v) 8. Terminate the program (q) >> Enter command: l Enter the number to count its occurrences: 7 [SUCCESS] 7 is found and the address of it's last occurrence in the linked list is: 0x24df8ae0 A simple program that provides the following operations on singly linked list. NOTE: The linked list only has one member: int num. Usage Command 1. Initilize a Singly Linked List (i) 2. Add a new node in the beginning of list (n) 3. Search for a node (s) 4. Delete a node (d) 5. Sort the nodes (o) 6. Find last Occurance (l) 7. View all nodes (v) 8. Terminate the program (q) >> Enter command: d Enter the number to search in the list: 7 A simple program that provides the following operations on singly linked list. NOTE: The linked list only has one member: int num. Usage Command 1. Initilize a Singly Linked List (i) 2. Add a new node in the beginning of list (n) 3. Search for a node (s) 4. Delete a node (d) 5. Sort the nodes (o) 6. Find last Occurance (l) 7. View all nodes (v) 8. Terminate the program (q) >> Enter command: v Current Node Addresss Member: num Member: next (node address) 0x24df8b00 1 0x24df8ac0 0x24df8ac0 3 (nil) A simple program that provides the following operations on singly linked list. NOTE: The linked list only has one member: int num. Usage Command 1. Initilize a Singly Linked List (i) 2. Add a new node in the beginning of list (n) 3. Search for a node (s) 4. Delete a node (d) 5. Sort the nodes (o) 6. Find last Occurance (l) 7. View all nodes (v) 8. Terminate the program (q) >> Enter command: q
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
size_t num_nodes = 0;
typedef unsigned long size_t;
struct singly_linked_list_node {
Question 17.14
Modify the delete_from_list function (Section 17.5) so that its first parameter has type struct node ** (a pointer to a pointer to the first node in a list) and its return type is void. delete_from_list must modify its first argument to point to the list after the desired node has been deleted.
- Answer
- Output
- Program
NOTE: Take reference from the function definition sll_delete_node
One way to visualize this is, consider that the first node in the linked list, pointed to by root is:
- address of first node - of type struct
singly_linked_list_node- has the address:0x1234. rootis, say, in address0x5678, whose content is0x1234.- When sending the address of
root, what we're essentially doing is, we're sending0x5678in the function.
When the first node is the one that needs to be deleted, prev will be NULL. Keep in mind the following assignments to the function parameters:
- list is a pointer to a pointer to a struct
singly_linked_list_nodevariable, which will be the address ofrootin this case. numis a number that needs to be checked in the linked list to delete the respective node.
When the first node is to be deleted, *list = (*list)->next is done. What this does is, as list is 0x5678, dereferencing it will point to the address 0x1234, and (*list)->next is the one next to the first pointer. What is essentially happening here is, we're changing the address of the first node with the address of the node which is being pointed to by the member of the first node's next member.
A simple program that provides the following operations on singly linked list. NOTE: The linked list only has one member: int num. Usage Command 1. Initilize a Singly Linked List (i) 2. Add a new node in the beginning of list (n) 3. Search for a node (s) 4. Delete a node (d) 5. Sort the nodes (o) 6. View all nodes (v) 7. Terminate the program (q) >> Enter command: i Enter the number to store: 3 A simple program that provides the following operations on singly linked list. NOTE: The linked list only has one member: int num. Usage Command 1. Initilize a Singly Linked List (i) 2. Add a new node in the beginning of list (n) 3. Search for a node (s) 4. Delete a node (d) 5. Sort the nodes (o) 6. View all nodes (v) 7. Terminate the program (q) >> Enter command: n Enter the number to store: 7 A simple program that provides the following operations on singly linked list. NOTE: The linked list only has one member: int num. Usage Command 1. Initilize a Singly Linked List (i) 2. Add a new node in the beginning of list (n) 3. Search for a node (s) 4. Delete a node (d) 5. Sort the nodes (o) 6. View all nodes (v) 7. Terminate the program (q) >> Enter command: n Enter the number to store: 1 A simple program that provides the following operations on singly linked list. NOTE: The linked list only has one member: int num. Usage Command 1. Initilize a Singly Linked List (i) 2. Add a new node in the beginning of list (n) 3. Search for a node (s) 4. Delete a node (d) 5. Sort the nodes (o) 6. View all nodes (v) 7. Terminate the program (q) >> Enter command: s Enter the number to search in the list: 7 The node has the following members: int num = 7 struct singly_linked_list_node *next = 0x2a3c9ac0 A simple program that provides the following operations on singly linked list. NOTE: The linked list only has one member: int num. Usage Command 1. Initilize a Singly Linked List (i) 2. Add a new node in the beginning of list (n) 3. Search for a node (s) 4. Delete a node (d) 5. Sort the nodes (o) 6. View all nodes (v) 7. Terminate the program (q) >> Enter command: v Current Node Addresss Member: num Member: next (node address) 0x2a3c9b00 1 0x2a3c9ae0 0x2a3c9ae0 7 0x2a3c9ac0 0x2a3c9ac0 3 (nil) A simple program that provides the following operations on singly linked list. NOTE: The linked list only has one member: int num. Usage Command 1. Initilize a Singly Linked List (i) 2. Add a new node in the beginning of list (n) 3. Search for a node (s) 4. Delete a node (d) 5. Sort the nodes (o) 6. View all nodes (v) 7. Terminate the program (q) >> Enter command: o The sorted array is: Address of element 0 and data 1 in list: 0x2a3c9b00 Address of element 1 and data 3 in list: 0x2a3c9ac0 Address of element 2 and data 7 in list: 0x2a3c9ae0 A simple program that provides the following operations on singly linked list. NOTE: The linked list only has one member: int num. Usage Command 1. Initilize a Singly Linked List (i) 2. Add a new node in the beginning of list (n) 3. Search for a node (s) 4. Delete a node (d) 5. Sort the nodes (o) 6. View all nodes (v) 7. Terminate the program (q) >> Enter command: d Enter the number to search in the list: 3 A simple program that provides the following operations on singly linked list. NOTE: The linked list only has one member: int num. Usage Command 1. Initilize a Singly Linked List (i) 2. Add a new node in the beginning of list (n) 3. Search for a node (s) 4. Delete a node (d) 5. Sort the nodes (o) 6. View all nodes (v) 7. Terminate the program (q) >> Enter command: v Current Node Addresss Member: num Member: next (node address) 0x2a3c9b00 1 0x2a3c9ae0 0x2a3c9ae0 7 (nil) A simple program that provides the following operations on singly linked list. NOTE: The linked list only has one member: int num. Usage Command 1. Initilize a Singly Linked List (i) 2. Add a new node in the beginning of list (n) 3. Search for a node (s) 4. Delete a node (d) 5. Sort the nodes (o) 6. View all nodes (v) 7. Terminate the program (q) >> Enter command: q
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
size_t num_nodes = 0;
typedef unsigned long size_t;
struct singly_linked_list_node {
Question 17.15
Show the output of the following program and explain what it does.
#include <stdio.h>
int f1(int (*f)(int));
int f2(int i);
int main(void)
{
printf("Answer: %d\n", f1(f2) );
return 0;
}
int f1(int (*f)(int))
{
int n = 0;
while ((*f) (n)) n++;
return n;
}
int f2(int i)
{
return i * i + i - 12;
}
- Answer
- Output
- Program
- When
f1is called frommainfunction, withf2as it's argument, which is valid asf1is expecting a parameter of type "function pointer" which take oneintas it's parameter. - On the function
f1,nis a local variable initialized as 0. In the while loop, functionf2is called with 0 as it's arugment, and in functionf2, 0 * 0 + 0 - 12 = -12 is returned. - As it is not 0 - the termination condition for a loop -
nis incremented, andnis now 1. Again the functionf2is called. Sof2is now called asf2(1). Inf2, 1 * 1 + 1 - 12 = -10 is returned. Again, loop is not terminated andnis computed again. In tabular representation:
| n | n × n + n − 12 | f₂(n) |
|---|---|---|
| 0 | -12 | -12 |
| 1 | -10 | -10 |
| 2 | -6 | -6 |
| 3 | 0 | 0 |
Notice that when n is 3, and f2 is called with n as its argument, f2 will return 0, which is indeed a valid loop termination condition. So the loop will terminate, and f1 will return n - which is 3 - to the main function. Hence, the output will be:
Answer: 3
NOTE: We can replace f1(f2) with f1(&f2), as f1 is expecting a pointer to a function which takes one int as a parameter and returns an int. Also, (*f)(n) in the while statement can be replaced with f(n), see #57 of Chapter's notes.
Answer: 3
#include <stdio.h>
int f1 (int (*f)(int));
int f2 (int i);
int main (void) {
printf("Answer: %d\n", f1(f2));
return 0;
}
Question 17.16
Write the following function. The call sum(g, i, j) should return g(i) + ... + g(j).
int sum(int (*f)(int), int start, int end);
- Program
- Output
#include <stdio.h>
int square (int num);
int sum (int (*f)(int), int start, int end);
void clear_input_stream (void);
int main (void) {
Enter the lower range and upper range (format: lower, upper): 4, 10 [LOG] The sum of the square is: 371
Question 17.17
Let a be an array of 100 integers. Write a call of qsort that sorts only the last 50 elements in a. (You don't need to write the comparison function).
- Program
- Output
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define ARR_SIZE 100
/*
* compare: compares the elements, returns 1 if element_1 is greater than element_2. -1 if
* element_1 is less than element_2, and 0 if element_1 is equal to element_2.
The program creates an array of 100 elements with elements being random. Index Element ----- ------- 0 1941316385 1 75077235 2 514846541 3 1607158871 4 1336410503 5 85955515 6 904287409 7 1446153425 8 2144213814 9 1317624333 10 200145319 11 592080744 12 1161752016 13 1860292508 14 985918990 15 1091625870 16 2065067071 17 1580500101 18 1810577701 19 170191379 20 727573905 21 922817915 22 1884134558 23 1163452175 24 2054249291 25 246212445 26 72588369 27 170824875 28 2036156163 29 136184031 30 704525244 31 1829988900 32 211261266 33 1219371785 34 1289664123 35 1547671769 36 1305327301 37 46467885 38 846341547 39 1302057467 40 1364092218 41 1046486866 42 1894138211 43 378360586 44 759295726 45 732573554 46 1469986456 47 676879149 48 165590007 49 1133080510 50 40443519 51 117904840 52 194182188 53 222319797 54 233994720 55 329166106 56 401111651 57 575695775 58 583721438 59 654715624 60 690530540 61 701547915 62 718606399 63 829933884 64 847070528 65 867137922 66 870608175 67 893163912 68 910873869 69 953852230 70 1024116072 71 1067745978 72 1276886262 73 1332212816 74 1497396627 75 1511391332 76 1622182641 77 1651155082 78 1669434273 79 1687126250 80 1690775775 81 1696210911 82 1737243660 83 1742722471 84 1757944398 85 1760301834 86 1769059922 87 1787796134 88 1827580256 89 1876837876 90 1909902325 91 1950345845 92 1962664068 93 2055898425 94 2056616087 95 2098226028 96 2116458009 97 2129204456 98 2133488943 99 2143834123
Question 17.18
Modify the compare_parts function so that parts are sorted with their numbers in descending order.
- Program
- Output
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
/* For demonstration purposes. Actual structure contains name, and on_hand members as well. */
struct part {
int number;
};
How many parts do you want to allocate: 2 Inserting random numbers for part's member (int number). Index Address Member (number) ----- ------- --------------- 0 0x77e2ac0 897051574 1 0x77e2ac4 153336298
Question 17.19
Write a function that, when given a string as its argument, searches the following array of structures for a matching command name, then calls the function associated with that name.
struct {
char *cmd_name;
void (*cmd_pointer)(void);
} file_cmd[]=
{{"new", new_cmd },
{"open", open_cmd },
{"close", close_cmd },
{"close all", close_all_cmd },
{"save", save_cmd },
{"save as", save_as_cmd },
{"save all", save_all_cmd },
{"print", print_cmd },
{"exit", exit_cmd },
};
- Program
- Output
#include <stdio.h>
#define CMD_LEN 10
void new_cmd (void);
void open_cmd (void);
void close_cmd (void);
void close_all_cmd (void);
void save_cmd (void);
The following commands are available: Command Usage ------- ------ new new command open open command close close command close all close all command save save command save as save as command save all save all command print print command exit exit command >> Enter command: print Invoked the print_cmd function.
Programming Projects
Project 17.1
Modify the inventory.c program of Section 16.3 so that the inventory array is allocated dynamically and later reallocated when it fills up. Use malloc initially to allocate enough space for an array of 10 part structures. When the array has no more room for new parts, use realloc to double its size. Repeat the doubling step each time the array becomes full.
- Program
Makefile
main.c
utils.c
utils.h
Project 17.2
Modify the inventory.c program of Section 16.3 so that the p(print) command calls qsort to sort the inventory array before it prints the parts.
- Program
Makefile
main.c
utils.c
utils.h
Project 17.3
Modify the inventory2.c program of Section 17.5 by adding an e(erase) command that allows the user to remove a part from the database.
- Program
Makefile
main.c
readline.c
readline.h
Project 17.4
Modify the justify program of Section 15.3 by rewriting the line.c file so that it stores the current line in a linked list. Each node in the list will store a single word. The line array will be replaced by a variable that points to the node containing the first word. This variable will store a null pointer whenever the line is empty.
- Program
Makefile
line.c
line.h
main.c
quote
temp
word.c
word.h
Project 17.5
Write a program that sorts a series of words entered by the user:
Enter word: foo
Enter word: bar
Enter word: baz
Enter word: quux
Enter word:
In sorted order: bar baz foo quux
Assume that each word is no more than 20 characters long. Stop reading when the user enters an empty word (i.e., presses Enter without entering a word). Store each word in a dynamically allocated string, using an array of pointers to keep track of the strings, as in the remind2.c program (Section 17.2). After all words have been read, sort the array (using any sorting technique) and then use a loop to print the words in sorted order. Hint: Use the read_line function to read each word, as in remind2.c.
- Program
Makefile
main.c
utils.c
utils.h
Project 17.6
Modify Programming Project 5 so that it uses qsort to sort the array of pointers.
- Program
Makefile
main.c
utils.c
utils.h
Project 17.7
(C99) Modify the remind2.c program of Section 17.2 so that each element of the reminders array is a pointer to a vstring structure (see Section 17.9) rather than a pointer to an ordinary string.
- Program
Makefile
main.c