### Exercises: Computer Systems Basics

These exercises will help you prepare for quiz questions you may see for Block 1: Computer Systems Basics.

Acknowledgements: These exercises were originally developed for Harvard's CS 61 course and were kindly shared by Eddie Kohler.

#### BASICS-1. Sizes and alignments

QUESTION BASICS-1A. True or false: For any non-array type X, the size of X (`sizeof(X)`) is greater than or equal to the alignment of type X (`alignof(X)`).

QUESTION BASICS-1B. True or false: For any type X, the size of `struct Y { X a; char newc; }` is greater than the size of X.

QUESTION BASICS-1C. True or false: For any types `A1`...`An` (with `n` ≥ 1), the size of `struct Y` is greater than the size of `struct X`, given:

``````struct X {
A1 a1;
...
An an;
};
``````
``````struct Y {
A1 a1;
...
An an;
char newc;
};
``````

QUESTION BASICS-1D. True or false: For any types `A1`...`An` (with `n` ≥ 1), the size of `struct Y` is greater than the size of `union X`, given:

``````union X {
A1 a1;
...
An an;
};
``````
``````struct Y {
A1 a1;
...
An an;
};
``````

QUESTION BASICS-1E. Assume that structure `struct Y { ... }` contains K `char` members and M `int` members, with KM, and nothing else. Write an expression defining the maximum `sizeof(struct Y)`.

QUESTION BASICS-1F. You are given a structure ```struct Z { T1 a; T2 b; T3 c; }``` that contains no padding. What does ```(sizeof(T1) + sizeof(T2) + sizeof(T3)) % alignof(struct Z)``` equal?

QUESTION BASICS-1G. Arrange the following types in increasing order by size. Sample answer: “1 < 2 = 4 < 3” (choose this if #1 has smaller size than #2, which has equal size to #4, which has smaller size than #3).

1. `char`
2. `struct minipoint { uint8_t x; uint8_t y; uint8_t z; }`
3. `int`
4. `unsigned short`
5. `char**`
6. `double`

#### BASICS-2. Memory regions

Consider the following program:

``````struct ptrs {
int** x;
int* y;
};

struct ptrs global;

void setup(struct ptrs* p) {
int* a = malloc(sizeof(int));
int* b = malloc(sizeof(int));
int* c = malloc(sizeof(int));
int* d = malloc(sizeof(int));
int* e = malloc(sizeof(int) * 2);
int** f = malloc(4 * sizeof(int*));
int** g = malloc(sizeof(int*));

*a = 0;
*b = 0;
*c = (int) a;
*d = *b;
e = 29;
e = (int) &d;

f = b;
f = c;
f = 0;
f = 0;

*g = c;

global.x = f;
global.y = e;

p->x = g;
p->y = &e;
}

int main(int argc, char** argv) {
stack_bottom = (char*) &argc;
struct ptrs p;
setup(&p);
do_stuff(&p);
}
``````

This program allocates objects `a` through `g` on the heap and then stores those pointers in some stack and global variables. We recommend you draw a picture of the state `setup` creates.

QUESTION BASICS-2A. Assume that `(uintptr_t) a == 0x8300000`, and that `malloc` returns increasing addresses. Match each address to the most likely expression with that address value. The expressions are evaluated within the context of `main`. You will not reuse an expression.

Value Expression
1. 0x8300040 A. `&p`
2. 0x8049894 B. `(int*) *p.x`
3. 0x8361AF0 C. `&global.y`
4. 0x8300000 D. `global.y`
5. 0xBFAE0CD8 E. `(int*) *p.y`

#### BASICS-3. Data representation

Assume a 64-bit x86-64 architecture unless explicitly told otherwise.

Write your assumptions if a problem seems unclear, and write down your reasoning for partial credit.

QUESTION BASICS-3A. Arrange the following values in increasing numeric order. Assume that `x` is an `int` with value 8192.

 1 `EOF` 5 `1000` 2 `x & ~x` 6 `(signed char) 65535` 3 `(signed char) 0x47F` 7 The size of a memory page 4 `x | ~x` 8 `-0x80000000`

A possible answer might be “a < b < c = d < e < f < g < h.”

For each of the remaining questions, write one or more arguments that, when passed to the provided function, will cause it to return the integer 61 (which is 0x3d hexadecimal). Write the expected number of arguments of the expected types.

QUESTION BASICS-3B.

``````int f1(int n) {
return 0x11 ^ n;
}
``````

QUESTION BASICS-3C.

``````int f2(const char* s) {
return strtol(s, nullptr, 0);
}
``````

``````int f3(const char* s) {
return strtol(s, nullptr, 0);
}
``````

#### BASICS-4. Sizes and alignments

Assume a 64-bit x86-64 architecture unless explicitly told otherwise.

Write your assumptions if a problem seems unclear, and write down your reasoning for partial credit.

QUESTION BASICS-4A. Use the following members to create a struct of size 16, using each member exactly once, and putting `char a` first; or say “impossible” if this is impossible.

1. `char a;` (we’ve written this for you)
2. `unsigned char b;`
3. `short c;`
4. `int d;`
``````struct size_16 {
char a;

};
``````

QUESTION BASICS-4B. Repeat Part A, but create a struct with size 12.

``````struct size_12 {
char a;

};
``````

QUESTION BASICS-4C. Repeat Part A, but create a struct with size 8.

``````struct size_8 {
char a;

};
``````

QUESTION BASICS-4D. Consider the following structs:

``````struct x {
T x1;
U x2;
};
struct y {
struct x y1;
V y2;
};
``````

Give definitions for T, U, and V so that there is one byte of padding in `struct x` after `x2`, and two bytes of padding in `struct y` after `y1`.

#### BASICS-5. Dynamic memory allocation

QUESTION BASICS-5A. True or false?

1. `free(nullptr)` is an error.
2. `malloc(0)` can never return `nullptr`.

QUESTION BASICS-5B. Give values for `sz` and `nmemb` so that `calloc(sz, nmemb)` will always return `nullptr` (on a 64-bit x86 machine), but `malloc(sz * nmemb)` might or might not return null.

Consider the following 8 statements. (`p` and `q` have type `char*`.)

1. `free(p);`
2. `free(q);`
3. `p = q;`
4. `q = nullptr;`
5. `p = (char*) malloc(12);`
6. `q = (char*) malloc(8);`
7. `p = 0;`
8. `q = 0;`

QUESTION BASICS-5C. Put the statements in an order that would execute without error or evoking undefined behavior. Memory leaks count as errors. Use each statement exactly once. Sample answer: “abcdefgh.”

QUESTION BASICS-5D. Put the statements in an order that would cause one double-free error, and no other error or undefined behavior (except possibly one memory leak). Use each statement exactly once.

QUESTION BASICS-5E. Put the statements in an order that would cause one memory leak (one allocated piece of memory is not freed), and no other error or undefined behavior. Use each statement exactly once.

QUESTION BASICS-5F. Put the statements in an order that would cause one boundary write error, and no other error or undefined behavior. Use each statement exactly once.

#### BASICS-6. Pointers and debugging allocators

You are debugging some students’ `dmalloc` code from Project 2. The codes use the following metadata, which tracks allocations as a linked list:

``````struct meta { ...
meta* next;
meta* prev;
};

``````

Their linked-list manipulations in `dmalloc` are similar.

``````void* dmalloc(size_t sz, const char* file, int line) {
...
meta* m = (meta*) ptr;
m->prev = nullptr;
}
...
}
``````

But their linked-list manipulations in `dfree` differ.

Alice’s code:

``````void dfree(void* ptr, ...) { ...
meta* m = (meta*) ptr - 1;
if (m->next != nullptr) {
m->next->prev = m->prev;
}
if (m->prev == nullptr) {
} else {
m->prev->next = m->next;
}
...
}
``````

Bob’s code:

``````void dfree(void* ptr, ...) { ...
meta* m = (meta*) ptr - 1;
if (m->next) {
m->next->prev = m->prev;
}
if (m->prev) {
m->prev->next = m->next;
}
...
}
``````

Chris’s code:

``````void dfree(void* ptr, ...) { ...
meta* m = (meta*) ptr - 1;
m->next->prev = m->prev;
m->prev->next = m->next;
...
}
``````

Donna’s code:

``````void dfree(void* ptr, ...) { ...
meta* m = (meta*) ptr - 1;
if (m->next) {
m->next->prev = m->prev;
}
if (m->prev) {
m->prev->next = m->next;
} else {
}
...
}
``````

You may assume that all code not shown here is correct.

QUESTION BASICS-6A. Whose code will segmentation fault on this input? List all students that apply.

``````int main() {
void* ptr = malloc(1);
free(ptr);
}
``````

QUESTION BASICS-6B. Whose code might report something like “`invalid free of pointer [ptr1], not allocated`” on this input? (Because a list traversal starting from `mhead` fails to find `ptr1`.) List all students that apply. Don’t include students whose code would segfault before the report.

``````int main() {
void* ptr1 = malloc(1);
void* ptr2 = malloc(1);
free(ptr2);
free(ptr1);   // <- message printed here
}
``````

QUESTION BASICS-6C. Whose code would improperly report something like “`LEAK CHECK: allocated object [ptr1] with size 1`” on this input? (Because the `mhead` list appears not empty, although it should be.) List all students that apply. Don’t include students whose code would segfault before the report.

``````int main() {
void* ptr1 = malloc(1);
free(ptr1);
print_leak_report();
}
``````

QUESTION BASICS-6D. Whose linked-list code is correct for all inputs? List all that apply.