Safe alternatives — strncpy, snprintf, strlcpy
WHY do we need these at all?
char buf[8];
strcpy(buf, "hello world"); // 12 bytes into 8 → OVERFLOWThe fix: pass the size of buf so the copy can stop in time. Three tools do this, and they differ in one crucial detail each.
strncpy — the bounded copy with a trap
snprintf — formatting that can't overflow
strlcpy — the one that does it all right (BSD)

Comparison table (memorize this, skip the rest)
| Function | Caps to | Always null-terminates? | Return value | Truncation check |
|---|---|---|---|---|
strcpy |
nothing | yes (if no overflow) | dest ptr | ❌ unsafe |
strncpy |
n bytes |
NO | dest ptr | manual |
snprintf |
size (incl. \0) |
YES | would-be length | r >= size |
strlcpy |
size-1 |
YES | strlen(src) |
ret >= size |
Recall Feynman: explain to a 12-year-old
Imagine pouring water into a cup. strcpy keeps pouring even when the cup is full — water spills everywhere and ruins your desk (that's a crash or a hack). The "safe" pourers first ask "how big is the cup?" strncpy stops pouring but sometimes forgets to put the lid on (no '\0'). snprintf always leaves room for the lid and tells you "you wanted more than fit." strlcpy is the polite one: stops in time, always puts the lid on, and whispers how much you actually had. The size argument is the question "how big is the cup?" — never skip it.
Flashcards
What single extra argument makes the safe string functions safe?
When does strncpy fail to null-terminate?
>= n (the size limit): it copies exactly n bytes and adds no '\0'.What is the standard fix after a strncpy(dest, src, sizeof(dest)-1)?
dest[sizeof(dest)-1] = '\0'; to guarantee termination.Why copy at most sizeof(dest)-1, not sizeof(dest)?
'\0'; capacity − 1 is the max content.Does snprintf always null-terminate?
size > 0, it always writes a terminating '\0'.What does snprintf return and how do you detect truncation?
'\0'); truncation happened iff return >= size.How does strlcpy differ from strncpy?
strlcpy always null-terminates and doesn't zero-pad; it caps at size-1 and returns strlen(src).Why is strlcpy not always usable?
Given char b[8]; snprintf(b,8,"id=%d",12345); what is in b and what does it return?
b = "id=1234" (7 chars + null); returns 8, flagging truncation since 8 >= 8.What memory bug do these functions prevent?
Connections
- C strings and the null terminator
- Buffer overflow and stack smashing
- strcpy and sprintf (unsafe)
- sizeof vs strlen
- Format strings and printf family
- Memory safety and undefined behavior
Concept Map
Hinglish (regional understanding)
Intuition Hinglish mein samjho
Dekho, C mein char buf[8] ka matlab hai sirf 8 byte ki jagah — usse zyada likhoge to memory overflow ho jaati hai, aur yahi cheez crash aur hacking ka sabse bada kaaran hai. strcpy aur sprintf size check hi nahi karte, isliye unhe "unsafe" bolte hain. Safe versions ek extra argument maangte hain: destination ka size kitna hai? Bas yahi ek number poora khel hai.
Teen tools yaad rakho. strncpy(dest, src, n) zyada se zyada n byte copy karta hai — par ek dhokha hai: agar source poora bhar gaya (n ya usse bada), to woh '\0' (null terminator) nahi lagaata. Tabhi humesha khud se dest[sizeof(dest)-1] = '\0'; likhna padta hai, warna string ka end hi nahi milega aur strlen/printf garbage padhne lagenge.
snprintf(dest, size, fmt, ...) sabse aaram-daayak hai: yeh humesha null-terminate karta hai aur kabhi overflow nahi karta. Iska return value bataata hai ki kitne characters likhne the (chahe room na ho) — agar return >= size, samajh jaao truncation ho gaya. strlcpy(dest, src, size) BSD ka hai, donon achhi baatein karta hai (overflow nahi, null hamesha lagta hai) aur strlen(src) return karta hai — par yeh standard C mein nahi hai, har platform pe nahi milega.
Yaad rakhne ka mantra: "n forgets the knot, printf aur l always tie it." Matlab strncpy null bhool sakta hai, par snprintf aur strlcpy hamesha null laga dete hain. Capacity C mein content hamesha C-1 tak hi, kyunki ek byte null ke liye reserve hai.