B. Undefined-behavior and pitfalls cheat sheet
- Signed overflow is UB; unsigned wraps predictably — Section 3.3, 28.
arr[i] is *(arr + i); there is no bounds check, ever — Section 6.1.
- Arrays decay to pointers on function-call;
sizeof on a decayed pointer
gives the pointer's size, not the array's — Section 6.1.
- Never return a pointer to a local (stack) variable — Section 5.1.
strcpy/strcat/sprintf/gets have no bound; prefer
snprintf/strlcpy/fgets — Section 7.2, 29.
malloc's return value is not guaranteed non-NULL; always check —
Section 10.1.
- Match every
malloc/strdup/_new with exactly one free/_free;
never twice, never after — Section 10.2, 10.3.
free(NULL) is always safe; make your own _free functions mirror
that — Section 10.3.
- Data races are UB, not just "unpredictable" — the compiler may assume
they don't happen — Section 20.1, 28.
- Format-string/argument mismatches in
printf/scanf are UB —
Section 3.2, 22.1.
va_arg's type must match what the caller actually passed; there is no
runtime check — Section 22.1.
Generated from real-life-c-guide.md · 8 Oct 2026 16:36