Strings
C has no dedicated string type. Everything Chapters 6 and 7 covered — fixed-size arrays, no bounds checking, pointer arithmetic — applies directly to text, exactly as-is. This closing chapter of Course 1 is where those two chapters' consequences become the most historically significant.
Strings Are char Arrays
A string is just an array of char, nothing more.
Null Termination
The '\0' byte marks the end. There is no separate length field anywhere — C strings carry no length of their own. Rust's String stores its length directly, alongside the data; finding a C string's length means scanning forward until '\0' is found, an O(n) operation every single time, unlike Rust's O(1) length lookup.
String Literals vs. Char Arrays
A real, important distinction: char *s = "hello" points at a string literal, which may live in read-only memory — writing through s is undefined behavior. char s[] = "hello" copies the characters into a genuinely mutable local array.
string.h Functions
strcpy vs. strncpy — The Classic Buffer Overflow
strcpy copies a string with zero bounds checking — exactly Chapter 6's array-overflow problem, applied specifically to text. Copying a longer string into a smaller buffer silently writes past its end. This single mistake is one of the most historically significant vulnerability classes in software security.
strncpy takes a maximum length and is safer — but has its own genuine gotcha: if the source is at least n characters long, strncpy does not guarantee the result is null-terminated at all.
| Concept | Rust String | C |
|---|---|---|
| Length tracking | stored directly — O(1) lookup | none — scan for '\0', O(n) every time |
| Bounds-checked copy | always, by design | strcpy — never; strncpy — partially, with its own gotcha |
| Mutability of a literal | n/a — owned data is always mutable if declared so | a string literal is read-only; modifying it is UB |
"hello" (5 characters) needs 6 bytes, not 5 — one extra for '\0'. Forgetting this is one of the most common sizing mistakes in C.
>= n, strncpy copies exactly n bytes and stops — with no guarantee the result is null-terminated. Treating strncpy as a fully "safe" drop-in replacement for strcpy is itself a real, common mistake.
Coding Challenges
Declare a char array using the char s[] = "..." form, print it, modify one character, and print it again to confirm the modification worked.
📄 View solutionWrite a function that computes a string's length by manually scanning for the null terminator (without calling strlen), and compare its result against the real strlen() for a test string.
📄 View solutionExplain the specific gotcha with strncpy that makes it not a fully safe replacement for strcpy, and describe what a caller must do afterward to guarantee the result is properly null-terminated.
📄 View solutionChapter 8 Quick Reference — Course 1 Complete
- A C string is just a
chararray — no dedicated string type exists '\0'marks the end — no separate length is ever stored, unlike Rust'sStringchar *s = "..."is a read-only literal;char s[] = "..."is a genuine mutable copystrcpy— zero bounds checking, the classic buffer-overflow sourcestrncpy— bounded, but doesn't guarantee null-termination if the source is>= ncharacters- Always size a buffer for the content plus one byte for
'\0' - Course 1 complete. Course 2 picks up with structs, unions, and dynamic memory — C's own central safety-tradeoff chapter