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
  • 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
  • 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-freed memory, but mentioning that is not necessary)
  • 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 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].”
  • 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 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
  • 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 “wrong sizeof argument”, etc.)
    • fix: change size(struct p *) to size(struct p)
  • 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 ->

Copyright © 2023 Daniel Graham, John Hott and Luther Tychonievich.
Released under the CC-BY-NC-SA 4.0 license.
Creative Commons License