C Strings
Null-terminated buffers and the bugs that come from forgetting the terminator.
Seven pieces, and the whole chapter is really one idea: a C string isn't a real type, it's just a char array with a convention — a \0 byte marking where it ends.
char name[6] = "hello"; /* 'h','e','l','l','o','\0' — 6 bytes, not 5 */
char bad[5] = "hello"; /* no room for the terminator — this is already broken */"hello" needs 6 bytes, not 5 — the terminator is part of the string, not extra. Every function that reads a C string (printf("%s", ...), strlen, strcpy) keeps reading byte by byte until it finds that \0, with no idea where the buffer actually ends otherwise. Leave it off, or overwrite it, and those functions just keep walking into whatever memory comes next.
This is where most of the classic C string bugs actually come from — not exotic logic errors, just a missing or misplaced terminator that a length-based data structure (like a Python string) would never let happen in the first place.
Notes from readers
Comments — via GitHub