CSSE 132 Homework Review
Homework 4 Review: Pointers, Stack Frames, and Arguments
Review the written traces and the coding portion by keeping three things separate: a value, its address, and the storage that holds it. Allow about 10 minutes.
Why This Matters
Homework 4 connects C expressions to memory and ARM64 procedure calls. You explain which caller variables a function can change, count bytes in stack frames, and follow character pointers through argument strings. The coding portion then uses those string skills to interpret and validate decimal input.
Written Portion: A Copy of a Value or a Copy of an Address?
Core idea: C passes arguments by value. A function receives a copy of an integer or a copy of a pointer. Changing a copied integer leaves the caller's integer alone. Dereferencing a copied pointer can change the object whose address the caller supplied.
Worked Example: Two Different Assignments
void changeCopy(int n) { n = 14; }
void changeObject(int *p) { *p = 14; }
int score = 6;
changeCopy(score); // score remains 6
changeObject(&score); // score becomes 14
In the first call, only the function's local n changes. In the second, p holds a copy of score's address and *p names the caller's object. Reassigning p itself would change the local pointer, not the caller's object. Course descriptions may call this “pass by reference”; the C mechanism is passing an address by value.
Trace the Indices Before Naming a Loop
For a loop with index values 0, 2, 4 over {7, 1, -3, 8, 5}, a running total visits 7, -3, and 5: 0 → 7 → 4 → 9. The stride selects every second element starting at index zero. Name a function from its behavior, and name parameters from their roles: array, stride, and length tell you more than single letters.
The stride is in elements. C scales array[i] by the element size automatically. Do not multiply the index by 4 inside a C subscript just because an ARM64 integer load uses a byte address.
Written Portion: Allocated Bytes Are Not Always Used Bytes
A frame reserves space by moving sp toward lower addresses. Count the reservation separately from the distinct byte ranges occupied by saved values. On the course ARM64 system, an x register holds 8 bytes, a w register holds 4, and stack alignment is 16 bytes.
Worked Example: A Leaf Function's Frame
remember:
sub sp, sp, 32
str x0, [sp, 16] // bytes 16–23: saved pointer
str w1, [sp, 28] // bytes 28–31: saved integer
ldr w2, [sp, 28] // reads the same slot
add sp, sp, 32
ret
This example allocates 32 bytes and uses 8 + 4 = 12 distinct bytes for saved values. Unused space is 32 − 12 = 20 bytes. A later load does not allocate another slot. Count the stored pointer as 8 bytes even if the pointed-to object is a 4-byte integer.
Also recognize stack adjustment inside a memory instruction: str x30, [sp, -32]! lowers sp by 32 before storing the 8-byte return address. ldr x30, [sp], 32 loads from the current address, then raises sp by 32.
bl writes the return address into x30. A function that calls another function must preserve its own return address when needed, then restore it before ret. Passing the address of a local integer requires an x register for the address; accessing that integer uses a w register.
Reading the supplied listing: the Homework 4 stack example omits ret after increment restores sp. Its displayed frame sizes can still be counted, but executing it literally would fall through into the next function. The C behavior assumes that increment returns normally.
Written Portion: Trace Each Argument Pointer Independently
For ./trace sun fog, argc is 3: the program name counts too. argv[0] points to "./trace", argv[1] to "sun", and argv[2] to "fog". Each is a null-terminated string.
Copying an entry into char *p[3] copies an address, not the text. Advancing p[j] then changes that local pointer entry while argv[j] retains its original address. A three-entry local pointer array only has room for indices 0 through 2.
Worked Example: Read One Character from Each String
Imagine three local pointers, initially at the starts of "./trace", "sun", and "fog". Read one character from each in order, print a newline, then advance each pointer once. Stop after the shortest string's length, which is 3.
Round 0: '.' + 's' + 'f' → .sf
Round 1: '/' + 'u' + 'o' → /uo
Round 2: 't' + 'n' + 'g' → tng
There are three newline operations, one per round, rather than one per character. The first pointer now points at the 'r' in "./trace". With that pointer, %c prints r when given the dereferenced character; %s prints race when given the pointer.
Subtracting the advanced pointer from its original pointer gives 3, the number of characters traversed. Pointer subtraction measures elements and is valid for positions within the same array, including its one-past-end position.
When tracing the homework, use the actual program-name string from the command shown. Include it in the shortest-length calculation. Keep commented-out statements out of your trace, and distinguish printed output from the integer returned by main.
Coding Portion: Validate Text Before Doing Arithmetic
Create add.c in your Homework 4 directory. The program takes exactly two decimal arguments, each from 0 to 99. The assignment forbids atoi. The inputs arrive as strings, so adding their first character codes is not numeric addition.
Worked Example: Decimal Place Values
For the text "42", first establish that both characters are decimal digits. Subtracting '0' turns '4' into 4 and '2' into 2. Place values give 4 × 10 + 2 = 42. A one-character string needs only its units digit.
An equivalent accumulation rule is value = value * 10 + digit: starting from zero, the intermediate values for "42" are 4 and 42. This explains the conversion without providing the complete homework program.
- Check the argument count before accessing
argv[1]orargv[2]. Two supplied numbers requireargc == 3. - Check each complete string against the assignment's one- or two-digit nonnegative decimal format. An empty string, a sign, letters, or an extra character does not meet that format.
- Convert validated digits, then add the two integer values. Each input is at most 99, but their sum can be as large as 198.
- Choose the required output message and include its final newline. Avoid extra prompts or debugging output.
The required formats are Usage: ./add <num1> <num2>, Error: INPUT is not a number from 0 to 99., and Do you know that A + B = SUM?, with placeholders replaced by the relevant input or numbers. Match the PDF's spelling, spaces, punctuation, and newline.
Testing on the course Linux VM:
make add
./add 42 7
./test_add.sh
The provided script builds the program and compares output against support/test_add, stopping at the first failure. That helper is an ARM64 Linux executable. Also check boundaries and malformed strings manually: 0, 99, too many arguments, too few arguments, an empty argument, and a string containing a nondigit. A script pass is evidence, not a substitute for understanding validation. Submit add.c to Gradescope as the assignment directs.
Common Mistakes
p = ... changes the pointer; *p = ... changes its target.
Count unique occupied byte ranges, not repeated reads and writes.
argv[0] participates when the loop starts at zero.
A leading digit does not make "4x" valid. Validate the whole string.
Quick Reference
| Expression or rule | Meaning |
|---|---|
&x / *p | Address of x / object at p's address. |
| Unused frame space | Allocated bytes minus distinct occupied bytes. |
argv[i] / argv[i][j] | Argument string pointer / one character in that string. |
%s / %c | String starting at a pointer / a character value. |
ch - '0' | Numeric digit value after checking that ch is a decimal digit. |
Check Yourself
- If a function receives
int *p, does assigning*p = 11change only the local pointer? - A frame reserves 48 bytes, stores one
xregister and twowregisters in separate slots, and reloads all three. How many bytes are used and unused? - A pointer starts at
"plane"and advances twice. What does%sprint from there, and what is its difference from the original pointer? - Why is checking only that
argv[1][0]is a digit insufficient? - What is
argcfor./add 8 6, and what numeric sum should conversion produce?
Answers and Reasoning
- No. It writes 11 to the pointed-to object; the local pointer's address value stays the same.
- Used:
8 + 4 + 4 = 16bytes. Unused:48 − 16 = 32. Reloading does not occupy new bytes. ane; the difference is 2 characters.- Later characters could be invalid, as in
"8q", or the string could be too long. Check the complete input. - 3, including the program name. The numeric sum is 14.