# Page 1

**Question 1**

- Full for
`0xF2BFD67B`

or one digit off of that - Partial for 2 or 3 digits off of that; or for
`0x10044020`

or`0xE2BB965B`

**Question 2**

- Full for having both
`C`

and`D`

- Partial just one of the two, or both with one extra

**Question 3**

- Full for
`~(~x | ~y)`

or`(x ^ y) ^ (x | y)`

or any similar working expression - Half for correct but using logical instead of bitwise (e.g.
`!(!x || !y)`

)

**Question 4**

- Full for 8-bit number with 2nd and 3rd bit different (i.e.,
`?01?????`

or`?10?????`

) - Partial for wrong number of bits or different number with 2nd bit
`1`

# Page 2

**Question 5**

- Full for a readable diagram where
`s = x ^ y`

and`c = x & y`

, or the equivalent - Partial for the logic without gates, or gates with a small error

**Question 6**

- Full for (a) bytes 108 though 10B filled and (b) 78, 56, 34, 12
- Partial for just one of (a) right bytes in wrong cells or (b) big-endian (12, 34, 56, 78) or (c) nibble-swap (87, 65, 43, 21)

**Question 7**

- Full for marking the set {
`B`

,`F`

} - Partial for (a) having at least one of the correct answers and (b) no more than 2 false answers selected

**Question 8**

- Full for
`4`

or any expression that evaluates to`4`

- Partial for
`2`

or`8`

# Page 3

*Example Question 9 solutions*

```
int i=0;
L1:
if (i >= n) goto L2;
printf("Step %d\n", i+1);
i+=1;
goto L1;
L2:
```

```
int i=0;
goto L2;
L1:
printf("Step %d\n", i+1);
i+=1;
L2:
if (i < n) goto L1;
```

**Q9 loop-style goto**

- Full for having (a) no loops and (b) a label above (c) a
`goto`

to that label - Partial for having a label, a
`goto`

, and no loops, but every`goto`

is downward not upward

**Q9 correct behavior**

- Full if the
`goto`

-using code is functionally like the`for`

-using code.

**Question 10**

- Full for putting
`free(old)`

after the`if`

in`pop`

. No points off for other edits (note: as written, this problem cannot be solved without a use-after-free unless they make other edits). - Partial for having the
`free`

before the`if`

or having the right`free`

but another one somewhere else or for having the wrong argument to the correct`free`

.

# Page 4

*Example correct solutions*

```
f:
cmpq $0, %rsi;
je done;
subq %rsi, %rdi;
movq %rsi, %rax;
movq %rdi, %rsi;
movq %rax, %rdi;
callq f;
retq;
done:
movq %rdi, %rax;
retq
```

```
f:
cmpq $0, %rsi;
jne recur;
movq %rdi, %rax;
retq;
recur:
subq %rsi, %rdi;
xchg %rsi, %rdi;
jmp f;
```

**Q11 function**

- full for using a =
`%rdi`

, b =`%rsi`

, and return value =`%rax`

- no points off for swapping
`%rdi`

and`%rsi`

- no points off for swapping
- partial for different but plausible way of getting args/return values
- also take off points here for bad assembly, such as
- wrong operator order
- parens where they don’t belong
- using
`+`

or`+=`

instead of`leaq`

or`addq`

- putting return values on line with
`retq`

- …

**Q11 branching**

- full for both
- pairing condition-code-setting and
`je`

/`jne`

- correct control flow

- pairing condition-code-setting and
- partial for just one of the two

**Q11 recursion**

- full for both
- setting new args
- recursive-style
`callq`

and`retq`

(or`jmp`

)

- partial for just one of the two, or nontrivial mistakes in those

# Page 5

**Question 12**

- full for reasonable approximations of both
- memory pointed to by
`sum`

is uninitialized - contents of
`sum`

could be anything at all - (note: this could leak secrets about previously-
`free`

d memory, but mentioning that is not necessary)

- memory pointed to by
- partial for right undefined behavior, wrong consequence
- partial for wrong undefined behavior with clear description of its consequences

**Q13 description**

- full for “sums the vectors in a list of vectors” or approximation thereof, mentioning it
`malloc`

s the return value - partial for not mentioning
`malloc`

or giving a description of the code instead of its function

**Q13 example**

- full for any non-trivial example (i.e., non-empty list) and its results, no matter the presentation style
- e.g., “if
`list_of_vectors`

is [[1, 2, 3], [4, 5, 6]], returns [5, 7, 9]” is incomplete (doesn’t say how to make that array, what the other args are, etc) but sufficient for full credit. - also accept (wrong) backwards interpretations like “if
`list_of_vectors`

is [[1, 2, 3], [4, 5, 6]], returns [6, 15].”

- e.g., “if
- partial for only empty- or singleton-list example, or no or wrong results

# Page 6

*one correct solution*

```
long int strtol(const char *nptr, char **endptr, int base) {
long ans = 0, neg = 0, overflow = 0;
while (isspace(*nptr)) nptr += 1;
if (*nptr == '-') { neg = 1; nptr += 1; }
else if (*nptr == '+') { nptr += 1; }
for(; *nptr >= '0' && *nptr <= ('0'+base); nptr += 1) {
long next = (ans * base) + (*nptr - '0');
if (next - neg < ans) overflow = 1;
ans = next;
}
if (endptr) *endptr = (char *)nptr;
if (overflow) {
errno = ERANGE;
return neg ? LLONG_MIN : LLONG_MAX;
}
return neg ? -ans : ans;
}
```

**Q14 pre-number handling**

- full for leading isspace and one +/-
- partial if does not use sign or canont handle spaces

**Q14 number conversion**

- full for handling any base
- partial for partial attempt or just one base

**Q14 endptr**

- full for setting *endptr = nptr iff endptr != NULL
- partial if always does it, or wrong number of *

**Q14 overflow**

- full for
- check overflow = went negative
- set errno and return LLONG_MIN/MAX

- partial for one of those
- no points off for not handling the edge cases right

# Page 7

**Questions 15 through 17**

Function | `read` | `fread` | `fgets` | `fscanf` | `fgetc` | `getline` |
---|---|---|---|---|---|---|

Q15 | A | C | C | C | C | C |

Q16 | C | C | C (partial for A) | C | A | B (partial for C) |

Q17 | B | B | A | A | B | A |

If the have an answer set from the wrong column, give partial on each.

**Question 18**

The most correct answer is `C`

, as technically `free`

d memory is still on the heap. But we’re accepting `B`

as correct too for grading.

- full for
`B`

and/or`C`

- partial if have
`B`

and/or`C`

and also`A`

and/or`D`

**Question 19** (dropped due to overwhelming misunderstanding of question)

- full for
`C`

and`E`

- partial for
`C`

,`E`

, and other options too - partial for
`C`

and`D`

- partial for
`E`

Note : `D`

(which implies `E`

) is *not* the definition of garbage, it is a definition of *unreachable*

# Page 8

For both questions, if the fix is correct read the bug description generously.

**Question 20**

- full for
- bug:
`realloc`

might return a new pointer (or “heap buffer overflow”) - fix:
`x =`

in front of`realloc`

- bug:
- partial for “x could be on the stack” or other plausible but ruled-out-by-“correctly initialized” bugs

**Question 21**

- full for
- bug: allocates half as many
`struct p`

s as intended (or “heap buffer overflow” or “wrong`sizeof`

argument”, etc.) - fix: change
`size(struct p *)`

to`size(struct p)`

- bug: allocates half as many
- partial for “x could be on the stack” or other plausible but ruled-out-by-“correctly initialized” bugs
- partial for noticing and correcting the typo (missing
`;`

on last line) - no credit for false fixes, like “change
`.`

to`->`

”