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
or0xE2BB965B
Question 2
- Full for having both
C
andD
- 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
andc = 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 to4
- Partial for
2
or8
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 everygoto
is 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 theif
inpop
. 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 theif
or having the rightfree
but 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
%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 ofleaq
oraddq
- 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
andretq
(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
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/orC
- partial if have
B
and/orC
and alsoA
and/orD
Question 19 (dropped due to overwhelming misunderstanding of question)
- full for
C
andE
- partial for
C
,E
, and other options too - partial for
C
andD
- 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 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 p
s as intended (or “heap buffer overflow” or “wrongsizeof
argument”, 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->
”