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.
- Github Classroom Link: https://classroom.github.com/a/QE1LnwS1
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
-
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
-
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
-
The following function declaration will not compile.
void foobar( int a[][]);
Provide an explanation for what is wrong and how to fix it.
-
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?
-
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
atMARK
- In plain English, provide a description of how the line
int * p = (int *)a+4
works when the array dimensions areint[2][3]
. - Draw the memory diagram at
MARK
- What are the values of
-
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 atMARK
- Offer a plain English explanation for what exactly
int * q = &p[1]
is referring to ina
- Draw the memory diagram at
MARK
- What are the values of
-
Below are the results of two Tic-Tac-Toe games, player
o
wins game 1 while playerx
wins game 2. Unfortunately one of the players (x
oro
) has inserted some evil code to change the boards.Run the code below in the C visualizer and answer the questions below.
#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 do you notice about the pointers to the strings on the heap?
- What did the evil code do to the 2 boards and who inserted the evil code?
-
Answer the following questions:
- What does
malloc()
do? What are the advantages or disadvantages of usingmalloc()
, if any? - What is the difference between
malloc()
andcalloc()
?
- What does
-
A computer science major who struggles with 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.
-
What is the difference between a memory violation and a memory leak? Provide a small code example of each.
-
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?
-
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 listvoid del_list(llist_t * list)
: dealocates a linked listlist
void add_to_head(llist_t *list,int new_value)
: add thenew_value
to the head of the list.
-
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){ // Add the new_value to the end of the link list // FINISH ME }
-
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 add_to_tail(llist_t * list, int new_value){ list->head = _add_to_tail(list->head, new_value); } node_t * _add_to_tail(node_t * node, int new_value){ //FINISH ME! --- this one is tough! }