Week 01 Tutorial Questions

Revision of Pointers and Linked Lists

Pointers Revision

In these questions, you can use this template to draw your own diagrams. Click on the pencil icon under the diagram to edit it.

  1. Using a diagram, show how the state of memory changes after each line of code is executed.

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    int main(void) {
    	int a = 5;
    	int b = 123;
    
    	int *pa = &a;
    	int *pb = &b;
    
    	*pa = 6;
    	*pb = 234;
    
    	int c = *pa;
    	*pa = *pb;
    	*pb = c;
    
    	pa = pb;
    	*pa = 345;
    }
    
  2. Explain why the swap() function here does not work as intended:

    int main(void) {
    	int a = 5;
    	int b = 7;
    	swap(a, b);
    	printf("a = %d, b = %d\n", a, b);
    }
    
    void swap(int a, int b) {
    	int tmp = a;
    	a = b;
    	b = tmp;
    }
    

    Modify the code so that it works as intended. Show how the new version works using a diagram.

Malloc Revision

In these questions, you can use this template to visualise the code execution. Click on the pencil icon under the diagram to edit it.

  1. What does malloc do?

  2. Explain how these two pieces of code differ:

    int main(void) {
    	stackInt();
    }
    
    void stackInt(void) {
    	int a = 5;
    }
     
    
    int main(void) {
    	heapInt();
    }
    
    void heapInt(void) {
    	int *a = malloc(sizeof(int));
    	*a = 5;
    }
    
  3. Modify the code below so that it allocates the struct on the heap, instead of the stack.

    struct node {
    	int value;
    	struct node *next;
    };
    
    int main(void) {
    	struct node n;
    	n.value = 42;
    	n.next = NULL;
    }
    
  4. The following code creates an array of 5 integers on the stack and uses it to store some values. How can you allocate the array on the heap instead?

    int main(void) {
    	int a[5];
    	for (int i = 0; i < 5; i++) {
    		a[i] = 42;
    	}
    }
    
Linked List Revision
  1. Consider the following two linked list representations:

    // Representation 1
    struct node {
        int value;
        struct node *next;
    };
    
    
    
    
    
    int listLength(struct node *list);
    
    // Representation 2
    struct node {
        int value;
        struct node *next;
    };
    
    struct list {
        struct node *head;
    };
    
    int listLength(struct list *list);
    
    1. Compare the two representations diagramatically.
    2. How is an empty list represented in each case?
    3. What are the advantages of having a separate list struct as in Representation 2?
  2. Consider the following simple linked list representation:

    struct node {
    	int value;
    	struct node *next;
    };
    

    Write a function to sum the values in the list. Implement it first using while and then using for.

  3. Implement a function to delete the first instance of a value from a list, if it exists. Use the following list representation and prototype:

    struct node {
        int value;
        struct node *next;
    };
    
    struct node *listDelete(struct node *list, int value);
    

    How would the implementation and prototype be different if the following list representation was used instead?

    struct node {
        int value;
        struct node *next;
    };
    
    struct list {
    	struct node *head;
    };
    

Before starting this week's lab, make sure you properly understand the following topics: