Page 1
Question 1
- Full for 0xF2BFD67Bor one digit off of that
- Partial for 2 or 3 digits off of that; or for 0x10044020or0xE2BB965B
Question 2
- Full for having both CandD
- 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 ^ yandc = 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 4or any expression that evaluates to4
- Partial for 2or8
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 gototo that label
- Partial for having a label, a goto, and no loops, but everygotois downward not upward
Q9 correct behavior
- Full if the goto-using code is functionally like thefor-using code.
Question 10
- Full for putting free(old)after theifinpop. 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 freebefore theifor having the rightfreebut another one somewhere else or for having the wrong argument to the correctfree.
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 %rdiand%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 ofleaqoraddq
- 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 callqandretq(orjmp)
 
- 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 sumis uninitialized
- contents of sumcould be anything at all
- (note: this could leak secrets about previously-freed 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 mallocs the return value
- partial for not mentioning mallocor 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_vectorsis [[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_vectorsis [[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 freed memory is still on the heap. But we’re accepting B as correct too for grading.
- full for Band/orC
- partial if have Band/orCand alsoAand/orD
Question 19 (dropped due to overwhelming misunderstanding of question)
- full for CandE
- partial for C,E, and other options too
- partial for CandD
- 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: reallocmight return a new pointer (or “heap buffer overflow”)
- fix: x =in front ofrealloc
 
- 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 ps as intended (or “heap buffer overflow” or “wrongsizeofargument”, etc.)
- fix: change size(struct p *)tosize(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->”