Worksheet: C3 | CS 2113 Software Engineering - Spring 2022

# 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.

## Note

Attempt to answer these questions before running the code. This will improve your ability to analyize and reason about code without an IDE or compiler. This skill we be helpful on the exams.

## 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
``````

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
``````

3. The following function declaration will not compile.

``````void foobar( int a[][]);
``````

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

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?

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`

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`

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.

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

``````int main(){

int a[] = {0x42434445,
0x20212223};

short * b = (short *) &a[1]; //MARK

//prints the two bytes of the short as a hexaxdecimal

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`

9. Below are the results of two Tic-Tac-Toe games, player `o` wins game 1 while player `x` wins game 2. 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 of game 1 is: ...");
printf("The winner of game 2 is: ...");
}
``````

What did the evil code do to the 2 boards and who inserted the evil code?

• What does `malloc()` do? What are the advantages or disadvantages of using `malloc()`, if any?
• What is the difference between `malloc()` and `calloc()`?

11. 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;
} course_t;

int main() {

course_t *courses[3];

courses[0] = malloc(sizeof(course_t));

courses[1] = malloc(sizeof(course_t));
courses[1]->name = "Complex Tic Tac Toe Analysis";

courses[2] = malloc(sizeof(course_t));
courses[2]->name = "Algebra for CS Majors";

// Begin Evil Code inserted by student
courses[2] = malloc(sizeof(course_t));
courses[2]->name = "Algebra for CS Majors";

// Rest of program
// ...

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.

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

13. 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?
• If so, how many bytes of a memory violation occur? If not, explain why there is no violation.
• Does this program leak any memory?
• What is the output?

14. 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{
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`
• `void add_to_head(llist_t *list,int new_value)` : add the `new_value` to the head of the list.

15. Referring to the linked list structures above, complete the following functions over these lists without recursive calls (a function calling itself).

``````int sum(llist_t * list){
// return a single integer,
// which is the sum of all nodes' val

// FINISH ME
}

int max(llist_t * list){
// return a single integer,
// the maximum val among all the nodes

// FINISH ME
}

void add_to_tail(llist_t * list, int new_value){

// FINISH ME
}
``````

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

``````
int sum(llist_t * list){
}

int _sum(node_t * node){
//FINISH ME!
}

int min(llist_t * list){
}

int _min(node_t * node){
//FINISH ME!
}

void add_to_tail(llist_t * list, int new_value){