Worksheet: C3 | CS 2113 Software Engineering - Fall 2021

Worksheet: C3

Worksheets are self-guided activities that reinforce lectures. They are not graded for accuracy, only for completion. Worksheets are due by Sunday night before the next lecture.

Questions

  1. Examine the program below and complete the code.

    #include <stdio.h>
    
    #define NUM_ROWS 3
    #define NUM_COLS 3
    
    int main() {
    
        int matrix[NUM_ROWS][NUM_COLS] = { {2, 5, 1},
                                           {3, 9, 6},
                                           {8, 7, 4}};
    
        // WRITE CODE TO PRINT OUT THE MATRIX
    
    }
    

    Finish the code above so that the output is the following:

    2 5 1 
    3 9 6 
    8 7 4 
    

    Reveal Solution

  2. Examine the program below and complete the code.

    #include <stdio.h>
    
    #define NUM_ROWS 3
    #define NUM_COLS 3
    
    int main() {
    
        int matrix_a[NUM_ROWS][NUM_COLS] = { {2, 5, 1},
                                             {3, 9, 6},
                                             {8, 7, 4}};
    
        int matrix_b[NUM_ROWS][NUM_COLS] = { {4, 1, 6},
                                             {9, 7, 5},
                                             {3, 8, 2}};
    
        int matrix_c[NUM_ROWS][NUM_COLS];
    
        // https://en.wikipedia.org/wiki/Matrix_multiplication_algorithm#Iterative_algorithm
        /*
            For i from 1 to num_rows:
                For j from 1 to num_cols:
                    Let sum = 0
                    For k from 1 to num_cols:
                        Set sum = sum + (Aik * Bkj)
                    Set Cij = sum
        */
        
        // USING THE ALGORITHM ABOVE
        // WRITE CODE HERE TO MULTIPLY THE TWO MATRICES
        // PUT THE RESULT IN MATRIX_C
    
        // PRINT RESULTING MATRIX_C
    }
    

    Finish the code above so that the output is the following:

    56 45 39 
    111 114 75 
    107 89 91 
    

    Reveal Solution

  3. The following function deceleration will not compile.

    void foobar( int a[][]);
    

    Provide an explanation for what is wrong and how to fix it.

    Reveal Solution

  4. Examine the program below and answer the following questions.

    #include <stdio.h>
    
    int main() {
        int array[3][3] = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9} };
    
        printf("%d\n", *(*array + 4));
    }
    

    Attempt to answer these questions without running the code!

    • What is the output of this program?
    • Explain the memory layout of a two-dimensional array?

    Reveal Solution

  5. Examine the program below and answer the following questions.

    #include <stdio.h>
    #include <string.h>
    int main(){
        int a[2][3] = { {10,20,30}, {5,6,7} };
       
        int * p = (int *)a+4;
    
        p[1] = 42;
        //MARK
    }
    

    Attempt to answer these questions without running the code

    • What are the values of a at MARK
    • In plain English, provide a description of how the line int * p = (int *)a+4 works when the array dimensions are int[2][3].
    • Draw the memory diagram at MARK

    Reveal Solution

  6. Examine the program below and answer the following questions.

    int main(){
      int a[][3] = { {10,20,30}, 
                    {5,6,7},
                    {-1,-2,-3},
                    {17,19,21}};
    
      int ** p = &a[1];
      int * q =  &p[1];
      
      q[1] = 42;
      //MARK
    }
    

    Attempt to answer these questions without running the code

    • What are the values of a after at MARK
    • Offer a plain English explanation for what exactly int * q = &p[1] is referring to in a
    • Draw the memory diagram at MARK

    Reveal Solution

  7. What are the two possible byte ordering and which byte ordering does nearly all modern computers use?

    As an example of this byte ordering, explain how the integer 513 would be stored, byte-by-byte.

    Reveal Solution

  8. Examine the program below and answer the following questions.

    int main(){
    
      //two ints in hexadecimal
      int a[] = {0x42434445, 
                 0x20212223};
                 
      short * b = (short *) &a[1]; //MARK
      
      //prints the two bytes of the short as a hexaxdecimal
      // like 0xbeef or 0xdead
      
      printf("0x%0hx",b[0]);
      
      //so what is the short in b[0] as a hexadecimal?
    }
    
    

    Attempt to answer these questions without running the code

    • What is the output?
    • Offer an explanation for the output
    • Draw a memory diagram at MARK

    Reveal Solution

  9. Below are the results of two Tic-Tac-Toe games. Unfortunately one of the players (x or o) has inserted some evil code to change the boards.

    #include <stdio.h>
    #include <string.h>
    
    int main() {
      char *game_1[3] = {
        "o|x| ",
        "o|o|x",
        "x|x|o"};
    
    char *game_2[3] = {
          "x|x|o",
          "o|x| ",
          "o|x|o",
      };
      
      //Begin Evil Code
      for (int i = 0; i < 3; i++) {
        char **tmp = &game_1[i];
        game_1[i] = game_2[i];
        game_2[i] = *tmp;
      }
      //End Evil Code
    
      printf("The winner is...");
    }
    

    After the evil code was inserted, one player won. Which player, x or o inserted the evil code, so that they won?

    Reveal Solution

  10. A computer science major who can’t do algebra is trying to modify their grades. The student was able to hack into the administrative code and insert some Evil Code to change their grade.

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    typedef struct {
      char *name;
      char grade;
    } course_t;
    
    int main() {
    
      course_t *courses[3];
    
      courses[0] = malloc(sizeof(course_t));
      courses[0]->name = "Basket Weaving";
      courses[0]->grade = 'A';
    
      courses[1] = malloc(sizeof(course_t));
      courses[1]->name = "Complex Tic Tac Toe Analysis";
      courses[1]->grade = 'A';
    
      courses[2] = malloc(sizeof(course_t));
      courses[2]->name = "Algebra for CS Majors";
      courses[2]->grade = 'D';
    
      //... some admin code
    
      // Begin Evil Code inserted by student
      courses[2] = malloc(sizeof(course_t));
      courses[2]->name = "Algebra for CS Majors";
      courses[2]->grade = 'B';
    
      // Rest of program
      // ...
    
      printf("Your grades for the semester are ...\n");
      // prints grades
      free(courses[0]);
      free(courses[1]);
      free(courses[2]);
    }
    
    • Did the student introduce a memory leak?
    • If so, how many bytes were leaked?
    • Explain the memory leak or why there can’t be a memory leak.

    Reveal Solution

  11. What is the difference between a memory violation and a memory leak? Provide a small code example of each.

    Reveal Solution

  12. Consider the following code

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    typedef struct {
      char * name;
      short x;
      short y;
    } point_t;
    
    int main() {
      point_t * a = malloc(sizeof(point_t));
    
      char * tmp_name = "Point of Interest";
      a->name = malloc(sizeof(char)*strlen(tmp_name)+1);
      strcpy(a->name, tmp_name); //Copies the string on the right to the left
      a->x = 4;
      a->y = 1;
    
      point_t b;
      b = *a;
      free(a);
    
      printf("%s",b.name); //MARK
      free(b.name);
    }
    

    Attempt to answer these questions without running the code

    • Is printing at the indicated MARK a memory violation? Does this program leak any memory?
    • If so, how many bytes of a memory violation occur? If not, explain why there is no violation.
    • What is the output?

    Reveal Solution

  13. For the next few questions, consider that your implementing a Linked List in C using the following struct

    typedef struct node{
        int val;
        struct node * next;
    
    } node_t;
    typedef struct llist{
       node_t head;
       int len;    
    } llist_t;
    

    Write the following functions:

    • llist_t * new_list() : allocates a new empty linked list
    • void del_list(llist_t * list) : dealocates a linked list list

    Reveal Solution

  14. Referring to the linked list structures above, complete the following recursive functions over these lists

    
    int sum(llist_t * list){
        return _sum(list->head);
    }
    
    int _sum(node_t * node){
      //FINISH ME!
    }
    
    
    int min(llist_t * list){
        return _min(list->head);
    }
    
    int _min(node_t * node){
      //FINISH ME!
    }
    
    void append(llist_t * list, int new_value){
       list->head = _append(list->head, new_value);
    }
    
    node_t * _append(node_t * node, int new_value){
      //FINISH ME! --- this one is tough!
    }
    
    

    Reveal Solution