Lecture File
structs.pdf
Data & Memory
Struct memory layout, data modeling, and abstract data type design in C.
File/lecture name: structs.pdf
Main theme: C Structures, Memory Layout, and Abstract Data Types (ADTs)
Prereqs assumed by slides: Basic C syntax (variables, functions, malloc, free), understanding of stack frames and memory addresses.
What this lecture enables you to do:
struct.. and -> operators.collides).struct, declaring variables, and accessing members with the dot operator.translate function example showing mutation issues.->) vs. dereferencing ((*p).f).List ADT).Node and List structs, and implementing createList, addToFront, ith, setElem, removeItem.deleteNode and deleteList to prevent memory leaks and dangling pointers.Node structs to the client programmer.| Name | Definition | Why it matters | Common confusion / misconception | Tiny example |
|---|---|---|---|---|
Structure (struct) |
A user-defined aggregate data type that groups related variables of different types. | Allows passing complex data as a single unit to functions. | Structures are not objects (no methods/constructors in C). | struct Rect { int x, y, w, h; }; |
Dot Operator (.) |
Accesses a member of a structure when the left operand is a structure variable. | Direct access to fields without dereferencing. | Cannot be used on pointers to structures. | r1.x = 5; |
Arrow Operator (->) |
Accesses a member of a structure when the left operand is a pointer to that structure. | Shorthand for (*ptr).member. |
ptr->x is preferred over (*ptr).x. |
r->y = r->y + y; |
| Structure Memory Layout | Fields are stored contiguously in memory in declaration order (with potential padding). | Affects sizeof and how copying works. |
Fields are not necessarily adjacent due to alignment/padding. | sizeof(r1) includes padding. |
| Abstract Data Type (ADT) | A data type where the user interacts only via an interface, not the internal implementation. | Enables encapsulation and reusability. | C does not have built-in ADTs like Python's list. |
List ADT hides Node details. |
| Linked List | A data structure where nodes contain data and a pointer to the next node. | Allows dynamic sizing and efficient insertion/deletion at front. | ith operation is $O(n)$, not $O(1)$. |
struct Node { int data; struct Node *next; }; |
| Dangling Pointer | A pointer that points to memory that has been freed. | Accessing it causes undefined behavior/crashes. | free(n) before accessing n->next. |
deleteNode(n->next); free(n); |
| Stack Frame Copy | C copies structures by value onto the stack frame when passed to functions. | Efficient for small structs, inefficient for large ones. | Large structs should be passed by pointer. | translate(r1, ...) copies r1. |
How to Define a Structure:
struct TypeName { ... };;).struct Rect {
int x, y, w, h;
};
How to Declare and Initialize a Structure:
struct TypeName varName;{ .field = val, ... } for clarity.struct Rect r1 = {.x=1, .y=5, .h=1, .w=1};
How to Choose Passing Style (Value vs. Pointer):
r.x inside the function, you must pass &r or a pointer.How to Access Members via Pointer:
ptr->memberptr->member is equivalent to (*ptr).member.*r.x is wrong; (*r).x or r->x is correct.How to Implement an ADT Interface:
struct Node to the client.createList(), addToFront(), deleteList().How to Free a Linked List Safely:
next node before freeing the current node.next becomes a dangling pointer.deleteNode(n->next); free(n);.| Pattern Name | When to use it | Correct minimal example | Common bug + how to avoid it |
|---|---|---|---|
| Struct Initialization | When declaring a struct variable. | struct Rect r = {.x=0, .y=0}; |
Forgetting the semicolon after the closing brace. |
| Pointer Member Access | When the variable is a pointer to a struct. | r->x = 5; |
Using r.x when r is a pointer (compile error). |
| Const Pointer to Struct | When passing a struct to a function without mutation. | void func(const struct Rect *r); |
Forgetting const (allows accidental mutation). |
| Recursive Deletion | When freeing a linked list. | deleteNode(n->next); free(n); |
Freeing n before n->next (dangling pointer). |
| ADT Creation | When initializing a dynamic list. | struct List *l = createList(); |
Declaring struct List l; directly (stack allocation). |
r.x works, but r->x fails.r is a pointer, not a struct variable.r->x or dereference (*r).x.translate function does not change r1 in main.translate takes struct Rect r (copy), so changes are local.void translate(struct Rect *r, ...) and pass &r1.deleteList.free (dangling pointer).deleteList is called exactly once and no pointers to freed nodes are used.sizeof(r1) is larger than expected.ith function is slow ($O(n)$).Node pointer (breaks ADT).deleteList.free(l) called but nodes inside l->head not freed.deleteNode(l->head) before free(l).Node fields directly.struct Node is exposed in header.struct Node definition; only expose struct List.(*r).x vs r->x confusion.ptr->field is the standard idiom.malloc returns NULL.malloc before dereferencing.removeItem fails to update len.l->len = l->len - 1;.createList returns pointer to stack variable.struct List l; inside function, returned by value.malloc for heap allocation in createList.struct definition missing semicolon.; after closing brace.sizeof returns wrong size.#pragma pack if strict layout is needed (advanced).translate modifies r but main sees old value.struct Rect *r.printf("%lu\n", sizeof(r1)); if struct Rect has 4 int fields?
A: Depends on architecture (e.g., 16 or 32 bytes), but it will be a multiple of the alignment unit (e.g., 4 or 8). It is not necessarily 16 bytes due to padding.r1.x = 5; work but r1->x = 5; fail if r1 is declared as struct Rect r1?
A: r1 is a struct variable, not a pointer. The arrow operator -> is only for pointers.void translate(struct Rect *r, int x, int y), why is (*r).x valid but r.x invalid?
A: r is a pointer. r.x tries to access a member of the pointer itself (which is an address), not the struct it points to. (*r) dereferences it first.free(l) in deleteList before calling deleteNode(l->head)?
A: Undefined behavior. l->head becomes a dangling pointer. Accessing it later crashes.ith function $O(n)$?
A: Linked lists do not support random access. You must traverse from head to the ind-th node.struct Node directly?
A: Do not expose the struct Node definition in the header file; only expose functions that operate on struct List.struct List l; and struct List *l = malloc(...)?
A: The first is a stack variable (local scope, fixed size). The second is a heap variable (dynamic size, must be freed).struct Rect r1 = {.x=1, ...}; valid syntax?
A: It uses aggregate initialization, allowing you to specify fields by name.r is a pointer to struct Rect, what does r->x mean?
A: It means (*r).x. It accesses the x field of the struct pointed to by r.assert(ind < l->len); in ith?
A: It checks for out-of-bounds access before traversing the list.return l; in addToFront necessary?
A: To allow the caller to continue using the list pointer without needing to update the local variable manually.struct Rect?
A: Fields are contiguous in memory in declaration order (x, y, w, h), potentially with padding between them.struct Name { type field; }; (Semicolon required!)struct Name var;var.fieldptr->field(*ptr).fieldsizeof(var) (includes padding)malloc(sizeof(struct Name))free(ptr) (Only once per allocation)const struct Name *ptr (Read-only access)struct Name *createName() { ... malloc ... return ptr; }struct Node { int data; struct Node *next; };struct List { struct Node *head; size_t len; };deleteNode(n->next); free(n);struct).struct): A C type that bundles variables of different types..): Accesses a member of a structure variable.->): Accesses a member of a structure via a pointer.malloc) that persists beyond the stack frame.r.x = 5).malloc.std::vector or std::list.deleteNode, not general recursion patterns.Manually curated from summaries/structs.txt. Use this page as a study aid and cross-check official slides for grading-critical details.