Introduction to Systems Programming
Introduction to system-level programming with fundamental OS concepts, procedures, primitive data types, user-defined types. Topics may include process management, memory management, process coordination and synchronization, inter-process communication, file systems, networking, pointers, heap and stack memory management, and system/library calls.
Study notes
Independent, AI-drafted study guide · Public sources linked below · Added November 5, 2026
Independent C and systems guide aligned with the Fall 2026 public outline. The restricted instructor notes are linked for personal reading only; none of their text, examples, or assessment solutions is reproduced here.
Bits, types, addresses, and representation
Memory stores bits, while types determine how operations interpret those bits. An unsigned integer uses positional binary notation. For example, hexadecimal 0x2D represents 2 times 16 plus 13, or decimal 45. Signed representation, integer width, byte order, and floating-point behavior require attention to the implementation and language rules. A pointer value identifies an address suitable for a particular object type; an address alone does not establish that accessing it is valid. Use sizeof rather than assuming a type occupies the same number of bytes on every platform.
References: COMP 2401 A/B/C — Fall 2026 course outline · GNU — C Language Introduction and Reference Manual
Pointers, arrays, strings, and lifetime
The address-of operator obtains an object’s address; dereferencing accesses the referenced object while it is valid. An array stores elements contiguously, and pointer arithmetic advances in units of the pointed-to type. Many array expressions convert to a pointer to the first element, losing the array length information. A C string ends at a null character, so a buffer needs room for that terminator as well as its visible characters. Distinguish a null pointer from a pointer to an object whose stored value is zero. Never return a pointer to an automatic local object that has ceased to exist.
References: COMP 2401 A/B/C — Fall 2026 course outline · GNU — C Language Introduction and Reference Manual
Dynamic memory and ownership
Dynamic allocation creates storage whose lifetime must be managed explicitly. Record which component owns each allocation and when ownership transfers. Check allocation results before use, initialize state before reading it, and free each owned allocation exactly once. After freeing an object, every alias to it becomes unsuitable for access; setting one pointer to NULL does not repair other aliases. When resizing a buffer, preserve the original pointer until success is known. A useful debugging sketch labels allocation, owner, aliases, valid bounds, and final release for every heap object.
References: COMP 2401 A/B/C — Fall 2026 course outline · GNU — C Language Introduction and Reference Manual
Compilation, modules, streams, and error paths
Compilation translates source files; linking resolves references among object files and libraries. Headers describe interfaces, while source files hold implementations. A build tool uses dependencies to decide which targets require rebuilding. A successful compile does not establish runtime safety. For I/O, distinguish a stream’s logical data from buffering and underlying system operations. Check return values and partial transfers rather than assuming every requested byte was processed. Cleanup belongs on error paths as well as successful paths; otherwise a recoverable file error may leave leaked memory or an open descriptor.
References: COMP 2401 A/B/C — Fall 2026 course outline · GNU — C Language Introduction and Reference Manual
Processes, threads, IPC, and synchronization
A process has an execution environment and address space; threads within a process share substantial state while maintaining separate execution stacks. Concurrency allows operations to overlap in time, creating ordering questions even on one processor. A race occurs when correctness depends on an uncontrolled ordering of accesses. Protect a shared invariant with suitable synchronization rather than assuming one source-level statement is indivisible. Inter-process communication can use pipes, sockets, signals, or shared memory, each with its own semantics. Define message boundaries explicitly when using a byte-stream transport.
References: COMP 2401 A/B/C — Fall 2026 course outline · GNU — C Language Introduction and Reference Manual
Worked example: allocating a small reading buffer
To allocate n integer readings, first ensure n is valid and n * sizeof(int) cannot overflow the allocation size type. Allocate using the element type’s size, verify success, then initialize only indices 0 through n-1. For n = 3 and values 4, 7, 9, a sum loop visits three valid elements and produces 20. Reading readings[3] is outside the allocated object, even if the program appears to continue. Release the buffer when its owner finishes, and do not use any retained alias afterward.
int *readings = malloc(n * sizeof *readings);
if (readings == NULL) {
/* report allocation failure */
return;
}
for (size_t i = 0; i < n; ++i) readings[i] = 0;
/* use indices strictly below n */
free(readings);References: COMP 2401 A/B/C — Fall 2026 course outline · GNU — C Language Introduction and Reference Manual
Practice & worked answers
Original exercises for this guide.
1. Why can sizeof(pointer) not recover an allocated array’s length?
Show worked answer
It measures the pointer object itself. The allocation’s element count must be tracked separately or encoded in an owning abstraction that retains it.
2. Two threads increment the same counter without synchronization. Why can updates disappear?
Show worked answer
An increment can involve separate read, calculate, and write operations. Both threads can read the same old value and write the same new value; in C, an unsynchronized data race also invokes undefined behavior.
3. What is wrong with freeing a buffer and continuing through another pointer to it?
Show worked answer
The object’s lifetime has ended regardless of which alias is used. This is a use-after-free, and the storage may already belong to another allocation.
Public notes & references
Course sources establish the scope above. Reference materials support the explanations; linked lecture notes and books remain with their authors.
Topics
- process management
- memory management
- process coordination and synchronization
- inter-process communication
- file systems
- networking
- pointers
- heap and stack memory management
- system/library calls
Course catalogue
Prerequisites & course information
Precludes additional credit for SYSC 1006 , SYSC 2006 . Prerequisite(s): ( COMP 1006 or COMP 1406 ) with a minimum grade of C- . Lectures three hours a week, tutorial one and a half hours a week.