FINAL - PRACTICE QUESTION SOLUTIONS
CSE 29
WINTER 2025
This exam is closed book, no computer, and no calculator exam. You are allowed to use one note
sheet 8.5 x 11'' (both sides), written or printed. All pages of this booklet must be turned in. Do
not talk to anyone but an exam proctor during the exam. Turn off cell phones. Relax, Don’t
Panic, Breathe.
Recommendations: Save time (~20-30 minutes) for the coding question(s) at the end! Be
careful of “Select ONE” versus “Select ALL” questions.
Note for Winter 2025: There will NOT be a coding question on the actual final. However, we
have placed one here as extra practice.
WRITE ALL YOUR ANSWERS FOR THIS EXAM IN THEIR DESIGNATED SPACE
ONLY. YOU MAY LOSE POINTS IF YOU DON’T DO SO!
By signing your name below, you are agreeing that you will not discuss any part of this exam
with anyone who is not currently taking the exam in this room until after the exam has been
graded and returned to you. This includes posting any information about this exam on EdStem or
any other social media. Discussing any aspect of this exam with anyone outside of this room
constitutes a violation of the academic integrity agreement for CSE 30. You agree to the
statement: “While taking this examination, I have not witnessed any wrongdoing, nor have I
personally violated any conditions of this course’s integrity policy.”
To express your understanding with the above policy, please write the phrase below in the box,
and then sign your name below:
“I excel with integrity”
Signature:____________________________________________
Name (print):________________________________________
PID:________________________
CSE 29 Practice Final Solutions
Spring 2025
1. Bitwise + Byte Ordering
1. Consider the following code snippet:
# include <stdio.h>
void mystery(int num) {
int n1 = -(~num);
printf("%d\n", n1);
}
int n2 = ~(-num);
printf("%d\n", n2);
a) What happens when the bitwise operations are performed and assigned to n1 and n2.
Choose ONE.
i) n1 contains num-1, n2 contains num+1
ii) n1 contains num+1, n2 contains num-1
iii) n1 contains -num, n2 contains num+1
iv) n1 contains num+1, n2 contains -num
b) You have a main function which calls mystery(83). What is printed by each print
statement line?
84
82
Page 1
CSE 29 Practice Final Solutions
Spring 2025
2. Show how the following variable is represented in memory. Enter contents in HEX
ONLY starting with the prefix 0x.
unsigned int x = 0xDEADC0DE;
Address
Contents Big Endian
Order
(1 point)
Contents Little Endian Order
(1 point)
0x400
0xDE
0xDE
0x401
0xAD
0xC0
0x402
0xC0
0xAD
0x403
0xDE
0xDE
Page 2
CSE 29 Practice Final Solutions
Spring 2025
2. Dynamic Memory Allocation (Implementation)
Note: In this question,
● The size of a header is 4 bytes (instead of 8 as we had in PA3)
● The alignment of blocks is by 8 bytes (instead of 16 as we had in PA3)
1. Given a heap as shown in the top diagram, what does the heap look like after calling
free(ptr)? Use the empty bottom diagram to show your answer.
2. Given a heap as shown in the top diagram, what does the heap look like after calling the
following two malloc statements sequentially? Use each empty heap diagram to show
your answer.
void* ptr = vmalloc(5);
void* ptr2 = vmalloc(1);
Page 3
CSE 29 Practice Final Solutions
Spring 2025
3. Build Processes & Integer Representation
1. If we have an int i = 0xF41 in hexadecimal, how many minimum number of bits are
needed to store this integer and how many bits will the variable i take in the memory
space of C?
Bits needed to store - 4*3=12 bits
Bits variable i will take - 32 bits
2. What is the difference between compilation and linking in the C build process?
a. Compilation is the process of converting source code to machine code, while
linking is the process of combining object files to create an executable file.
b. Compilation is the process of creating object files, while linking is the process of
converting object files to machine code.
c. Compilation is the process of creating executable files, while linking is the
process of creating object files.
d. Compilation and linking are the same process.
3. What is the purpose of preprocessor directives in the C build process?
a. To include header files and define macros.
b. To generate object files.
c. To link object files into an executable.
d. To run the executable.
Page 4
CSE 29 Practice Final Solutions
Spring 2025
4. 1d Arrays + Pointers
1. Consider the following code snippet in C. Assume that the base address of array arr is
0x4000, and that our machine is big-endian.
int arr[] = {10, 20, 40, 30, 50, 60};
int *ptr = arr + 3;
Give the value for each of the following expressions, or state Unknown if it cannot be
determined. The value is defined to be the output seen when we use printf with a %d
format specifier.
Expression
Value
*(ptr - 3)
10
arr[4]
50
ptr[6]
Unknown
*( (int *)((char *)ptr + 4) )
50
*((char *)arr + 7)
20
*(arr + 2)
40
Page 5
CSE 29 Practice Final Solutions
Spring 2025
2. Consider the following code snippet in C, where we create a string and print out some
values:
int main() {
char text[] = "CSE 30 is awesome!!";
printf("ans1: %c\n", *text);
printf("ans2: %c\n", text[4]);
// Pay attention to the format specifier %s!
printf("ans3: %s\n", &text[4]);
}
What values will be printed for ans1, ans2, and ans3?
ans1
C
ans2
3
ans3
30 is awesome!!
Now suppose we execute the following line of code: text[6] = '\0';
What will a call to printf("%s\n", text) now return? CSE 30
Page 6
CSE 29 Practice Final Solutions
Spring 2025
5. 2d Arrays + Pointers to pointers
Note: in this question, assume that the size of a pointer is 4 bytes.
1. Consider the following 2D array arr:
int **arr;
arr = malloc(3 * sizeof(int *));
for (int i = 0; i < 3; i++) {
arr[i] = malloc(4 * sizeof(int));
}
If arr is 0x7F8E32, what is the value of arr[2][1]? Show your work.
Address
Value
Address
Value
0x7F8E32
0x868B0A
0x868B02
0x73
0x7F8E36
0x868C02
0x868B06
0x837
0x7F8E3A
0x868B42
0x868C02
0x363
0x868B3E
0x21
0x868B0A
0x2
0x868B42
0x32
0x868B0E
0x99
0x868B46
0x89
0x868B12
0x3A
0x868B4A
0xAA
0x868B16
0x87
0x89
arr = 0x7F8E32
&(arr[2]) = 0x7F8E3A
arr[2] = 0x868B42
arr[2][1] = 0x89
Page 7
CSE 29 Practice Final Solutions
Spring 2025
2. Consider the following C code snippet:
int arr[2] = {1, 10}
int *ptr = &arr[0];
int *ptr2 = ptr + 1;
int **ptr3 = &ptr2;
The contents of memory are:
Address
Value
Question: What is the value of the followi
expressions in hexadecimal? The first
one has been done for you.
0xFF85BCDC
0x10
1. arr[0]
0x1
0xFF85BCE0
0x1
2. arr[1]
0xA
0xFF85BCE4
0xA
3. ptr
0xFF85BCE0
0xFF85BCE8
0xFF85BCE0
4. ptr2
0xFF85BCE4
0xFF85BCEC
0xFF85BCE4
5. *ptr
0x1
0xFF85BCF0
0xFF85BCEC
6. *ptr2
0xA
0xFF85BCF4
0xFF85BCE1
7. ptr3
0xFF85BCEC
0xFF85BCF8
0xFF85BCF4
8. **ptr3
0xA
Page 8
CSE 29 Practice Final Solutions
Spring 2025
3. Consider the following code in C:
#include <stdio.h>
void my_function(int *ptr) {
*ptr = 42;
ptr = NULL;
}
int main() {
int x = 0;
int *ptr = &x;
my_function(ptr);
printf("*ptr = %d\n", *ptr);
return 0;
}
Will this code run successfully? Give the output below if it does, otherwise identify the error in the code.
*ptr = 42
Page 9
CSE 29 Practice Final Solutions
Spring 2025
6. Dynamic Memory Allocation
1. Suppose we have this code:
#include <string.h>
#include <stdlib.h>
struct mystruct {
int id;
char name[16];
char *description;
};
int main(void) {
struct mystruct *s1 = malloc(sizeof(struct mystruct));
struct mystruct s2;
s1->id = 5;
strcpy(s1->name, "Ocelot");
s1->description = "You're pretty good";
s2.id = 42;
strcpy(s2.name, "Snake");
s2.description = malloc(4);
strcpy(s2.description, "...");
// TODO: Deallocate stuff
}
Write the names of the variables and struct fields that you would call free() at the end
of the program (where the comment is) in order to prevent a memory leak.
s1, s2.description
Page 10
CSE 29 Practice Final Solutions
Spring 2025
2. Suppose you have the following C code:
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
void mix(int **a) {
int *parray = malloc(2 * sizeof(int));
parray[0] = 12;
parray[1] = 91;
*a = parray;
}
int main() {
int *a;
mix(&a);
printf("a[0] = %d and a[1] = %d\n", a[0], a[1]); // L14
free(a);
int **b = malloc(sizeof(int*));
*b = malloc(3 * sizeof(int));
mix(b);
printf("b[0][0] = %d, b[0][1] = %d\n", b[0][0], b[0][1]); // L19
free(b[0]);
free(b);
return 0;
}
Answer the following questions about the above code when it is compiled and executed. If any
of the answers are INDETERMINATE, you may write that as an option.
1. What is line 14 (first printf()) going to print?
a[0] = BLANK1 and a[1] = BLANK2
BLANK1 = 12
BLANK2 = 91
2. What is line 19 (second printf()) going to print?
b[0][0] = BLANK3 and b[0][1] = BLANK4
BLANK3 = 12
BLANK4 = 91
Page 11
CSE 29 Practice Final Solutions
Spring 2025
3. How many bytes of memory will be lost given that an int is 4 bytes?
12 bytes. Because memory allocated by `malloc(3*sizeof(int))` is
never freed. Mix method overrides that pointer so we lose it.
Page 12
CSE 29 Practice Final Solutions
Spring 2025
7. Stack vs Heap vs Data vs Code
1. Read the code below and answer the following questions:
# include <stdlib.h>
# define N 1
char* string = "Printing zeroes";
int* mallocExtraIntegers(int num)
{
int* allocated;
allocated = calloc(sizeof(int) * (num + N));
return allocated;
}
int doubleAmount(int num2){
return num2 * 2;
}
int main()
{
int* mem;
int first = 5;
int doubled = doubleAmount(num);
mem = mallocExtraIntegers(doubled);
for(int i = 0; i < (doubled + N); i++){
printf("%d", *(mem + i));
}
}
Page 13
CSE 29 Practice Final Solutions
Spring 2025
a. num2 is located on the:
Stack
Heap
Code
Data
b. allocated is located on the:
Stack
Heap
Code
Data
c. i (loop variable) is located on the:
Stack
Heap
Code
Data
d. string is located on the:
Stack
Heap
Code
Data
e. allocated[0] is located on the:
Stack
Heap
Code
Data
Page 14
CSE 29 Practice Final Solutions
Spring 2025
2. What would the stack frame look like when the following code is executed? Your answer
should represent the state of each stack frame before it is destroyed
#include <stdio.h>
void foo(int x, int y) {
int z = x + y;
printf("The value of z is %d\n", z);
}
int main() {
int a = 2;
int b = 3;
foo(a, b);
return 0;
}
Answer:
foo’s stack frame (below)
z: 5
y: 3
x: 2
main’s stack frame (below)
b: 3
a: 2
Page 15
CSE 29 Practice Final Solutions
Spring 2025
8. Structs in C
1. Given the following code. Assume everything is properly defined and initialized, please
choose the best option to fill in the blanks.
struct item{
char* name;
int quantity;
int price;
};
struct item obj1 = {"apple", 10, 2};
struct item *ptr_obj1 = &obj1;
struct item **dptr_obj1 = &ptr_obj1;
printf("Name: %s\n", _____(1)______);
printf("Quantity: %d\n", _____(2)_______);
printf("Price: %d\n", ______(3)_______);
1) "Name: apple"
(*dptr_obj1) → name
dptr_obj1 → name
dptr_obj1.name
None of the above
2) "Quantity: 10"
(*ptr_obj1).quantity
ptr_obj1.quantity
(*ptr_obj1) → quantity
None of the above
3) "Price: 2"
obj1 → price
(*obj1).price
obj1.price
None of the above
Page 16
CSE 29 Practice Final Solutions
Spring 2025
2. Choose the statement that best describes the behavior of the code:
struct node{
int count[500];
struct node *next;
};
struct node *start;
struct node arr[10];
printf("%ld\n", sizeof(struct node));
printf("%ld\n", sizeof(start));
A. The first printf will print 2004
B. The second printf will print 2004
C. Both printf will print 2004
D. Have an error because struct can not contain itself
E. Have an error because we cannot have an array of structures in C
NOTE: None of the above options are correct since a pointer is 8 bytes. This is a mistake in the
question as the previous options assumed that the size of a pointer is 4 bytes.
If the options were the following, then option A is the correct answer.
A. The first printf will print 2008
B. The second printf will print 2008
C. Both printf will print 2008
D. Have an error because struct can not contain itself
E. Have an error because we cannot have an array of structures in C
Page 17
CSE 29 Practice Final Solutions
Spring 2025
9. Coding Question
1. Assume you have the following struct ticket that represents an Autograder ticket.
Complete the missing parts of the following function that inserts a ticket at the beginning
of a linked list that represents the Autograder queue. You may assume that all calls to
malloc() are successful.
struct ticket {
char *question;
struct ticket *next;
};
void insert_new_ticket(struct ticket **phead, char *question) {
struct ticket *newticket = NULL;
// Create newticket on the heap and assign its members
newticket = malloc(sizeof(struct ticket));
newticket->question = malloc(strlen(question) + 1));
newticket->next = NULL;
strncpy(newticket->question, question, strlen(question)
+ 1);
// Insert the ticket at the beginning of the queue
newticket->next = *phead;
*phead = newticket;
Page 18
CSE 29 Practice Final Solutions
Spring 2025
2. Complete the missing parts of the following functions that transpose a specified section
of an image (represented by a 2D array). You can assume the specified section of the
image will be in the shape of a square (number of rows = number of columns) and that
the specified starting and ending rows and columns are valid.
Example:
r_start = 1
r_end = 2
c_start = 1
img: [[1, 2, 3],
[[5,8]
[4, 5, 6], => [6, 9]]
[7, 8, 9]]
c_end = 2
Note: Your program should work for any img (not just the 3x3 img shown above) and should not
modify img.
# define ROWS 3
# define COLS 3
int**
transpose_section(int
img[ROWS][COLS],
int
r_start,
int
r_end,
int c_start, int c_end) {
// Create a 2d array on the heap to store the transposed img
int num_rows = r_end - r_start + 1;
int num_cols = c_end - c_start + 1;
int **transposed = malloc(sizeof(int *) * num_rows);
for (int i = 0; i < num_rows; i++) {
transposed[i] = malloc(sizeof(int) * num_cols);
}
// Copy the transposed section to the new 2d array
for (int i = r_start; i < r_end + 1; i++) {
for (int j = c_start; j < c_end + 1; j++) {
transposed[j-c_start][i-r_start] = img[i][j];
}
}
return transposed;
}
Page 19
CSE 29 Practice Final Solutions
Spring 2025
10. File I/O
1. What among the following storage/memory devices has the MOST storage capacity.
a. RAM (main memory)
b. Solid State Drive (SSD)
c. Hard Disk Drive (HHD)
d. Registers
e. Cache
2. What among the following storage/memory devices has the LEAST latency.
a. RAM (main memory)
b. Solid State Drive (SSD)
c. Hard Disk Drive (HHD)
d. Registers
e. Cache
3. Explain the purpose of the open() and close() operations.
open(): An application announces its intention to access an I/O device by asking the
kernel to open the corresponding file. The kernel returns a
small nonnegative integer, called a descriptor, that identifies the file in all subsequent
operations on the file. The kernel keeps track of all information about the open file. The
application only keeps track of the descriptor.
close(): When an application has finished accessing a file, it informs the kernel by asking
it to close the file. The kernel responds by freeing the data structures it created when the
file was opened and restoring the descriptor to a pool of available descriptors. When a
process terminates for any reason, the kernel closes all open files and frees their memory
resources.
Page 20
CSE 29 Practice Final Solutions
Spring 2025
11. Operating System
1. What does fork() return in the parent process and the child process?
a. Return 0 in the parent and 1 in the child
b. Return pid of the child in the parent and 0 in the child
c. Return 0 in the parent and the pid of parent in the child
d. Return the pid of the child in the parent and the pid of the parent in the child
2. What among the following are true about exec? Select ALL that apply.
a. exec does not return if it is successful
b. exec takes the name of the program to be executed as it first argument
c. exec replaces the current process image with a new process image
d. exec returns 0 if it is successful
3. Consider the code snippet below with calls to fork (and with error handling code removed
just for readability sake):
1. pid_t ret;
2. printf("A\n");
3. ret = fork();
4. if(ret == 0) {
5.
printf("B\n");
6.
ret = fork();
7.
if(ret == 0) {
8.
printf("C\n");
9.
}
10.
printf("D\n");
11. } else {
12.
printf("E\n");
13.
ret = fork();
14.
printf("F\n");
15. }
16. printf("G\n");
Page 21
CSE 29 Practice Final Solutions
Spring 2025
a. Draw the process hierarchy created by executing this code.
Let's break down the execution:
1. Parent Process (P0):
printf("A\n");
ret = fork(); // creates a child process (P1).
2. Parent Process (P0):
Line 4: if(ret == 0) is false (since ret is the PID of P1).
Executes else {
Executes printf("E\n");
ret = fork(); creates another child process (P2).
Executes printf("F\n");
}
Executes printf("G\n");
3. First Child Process (P1):
Line 4: if(ret == 0) is true (since ret is 0 in child).
Executes printf("B\n");
ret = fork(); // creates a child process (P3).
Executes printf("D\n");
Executes printf("G\n");
4. Second Child Process (P2):
Executes printf("F\n");
Executes printf("G\n");
5. Third Child Process (P3):
Line 7: if(ret == 0) is true (since ret is 0 in child).
Executes printf("C\n");
Executes printf("D\n");
Executes printf("G\n");
P0
├── P1
│
└── P3
└── P2
Page 22
CSE 29 Practice Final Solutions
Spring 2025
b. For each process in the hierarchy, indicate its output sequence (the order in which it
executes printf’s).
There is no fixed order of final output (eg. the order each printf printed out
in your terminal), when the child process created, they will run
independently from parent, then it’s all depends on the OS to schedule
each process, and it may varies on many factors (eg. number processes,
schedule algorithm, etc) But each process should execute the printf in the
following order:
P0: AEFG
P1: BDG
P2: FG
P3: CDG
Page 23
CSE 29 Practice Final Solutions
Spring 2025
12. Virtual Memory & Paging
1. Complete the following table, filling in the missing entries and replacing each question
mark with the appropriate integer. Use the following units: K = 2^10 (Kilo), M = 2^20
(Mega), G = 2^30 (Giga), T = 2^40 (Tera), P = 2^50 (Peta), or E = 2^60 (Exa).
No. virtual address bits (n)
No. virtual addresses (N)
8
2
16
32
48
64
8
16
2
32
2
48
2
64
2
Largest
address
possible
virtual
8
= 256
2 − 1 = 255
= 64𝐾
2
= 4𝐺
2
= 256𝑇
2
= 16384𝑃
2
16
32
48
64
− 1 = 64𝐾 − 1
− 1 = 4𝐺 − 1
− 1 = 256𝑇 − 1
− 1 = 16384𝑃 − 1
This problem gives you some appreciation for the sizes of different address spaces. At
one point in time, a 32-bit address space seemed impossibly large. But now there are
database and scientific applications that need more, and you can expect this trend to
continue. At some point in your lifetime, expect to find yourself complaining about the
cramped 64-bit address space on your personal computer!
Page 24
CSE 29 Practice Final Solutions
Spring 2025
2. Determine the number of page table entries (PTEs) that are needed for the following
combinations of virtual address size (n) and page size (P ):
n
𝑃 =2
No. PTEs
16
4K
16
16
8K
8
32
4K
1M
32
8K
512K
𝑝
𝑝
Since each virtual page is 𝑃 = 2
𝑛
𝑝
𝑛−𝑝
2 /2 = 2
bytes, there are a total of
possible pages in the system, each of which needs a
page table entry (PTE).
Page 25
0
You can add this document to your study collection(s)
Sign in Available only to authorized usersYou can add this document to your saved list
Sign in Available only to authorized users(For complaints, use another form )