Structs
Challenge Gallery
Quick Reference
Declaring and using:
typedef struct {
char name[50];
int id;
double gpa;
} Student;
Student s = {"Alice", 1001, 3.85}; // Initialize
printf("%s: %.2f\n", s.name, s.gpa); // Access with .
Dot vs arrow:
| Have | Access with | Example |
|---|---|---|
Struct value Student s |
. |
s.name |
Struct pointer Student *p |
-> |
p->name |
p->name is shorthand for (*p).name.
Dynamic allocation:
Student *s = calloc(1, sizeof(Student)); // NOT sizeof(Student *)
strcpy(s->name, "Alice");
s->id = 1001;
s->gpa = 3.85;
// ... use s ...
free(s);
Nested free order:
// Struct with pointer field:
typedef struct { char *name; int id; } Record;
// FREE INNER FIRST:
free(r->name); // 1. Free the string
free(r); // 2. Free the struct
Common Pitfalls
- sizeof(Student *) vs sizeof(Student) — Pointer is 8 bytes. Struct might be 64 bytes. Wrong sizeof = buffer overflow.
- Shallow copy with pointer fields —
s2 = s1copies the pointer, not the data. Both share the string. Deep copy requires strcpy into new allocation. - Can’t compare with == — Must compare field by field. No built-in equals.
- Free order — Inner allocations first, outer struct last. Reverse order leaks memory.
- Forgetting -> with pointers —
p.nameon a pointer is a compile error. Usep->name. - Uninitialized fields — Struct fields are garbage unless initialized. Use
= {0}or set each field.