5.1.21 · Coding › C Programming
Intuition 80/20 core baat
Unsafe functions strcpy aur sprintf characters tab tak likhte hain jab tak '\0' nahi milta — ye kabhi destination ka size check nahi karte . Agar source buffer se bada ho, toh ye seedha end ke baad chale jaate hain aur memory corrupt kar dete hain (buffer overflow). "Safe" family se aapko ek extra argument chahiye: destination kitna bada hai? Bas wahi ek number poora game hai. Exactly us boundary par har function kya karta hai — yeh master kar lo, toh safe C string handling ka 80% ho gaya.
Definition Buffer overflow
Array ke end ke baad likhna. C mein, char buf[8] sirf 8 bytes hai; kuch bhi aapko 9th likhne se nahi rokta. 9th byte jo bhi memory aage hai — doosra variable, return address, kuch bhi — wahan land karti hai. Yeh C mein security exploits ka #1 source hai.
char buf [ 8 ];
strcpy (buf, "hello world" ); // 12 bytes into 8 → OVERFLOW
Fix: buf ka size pass karo taaki copy waqt par ruk sake . Teen tools yeh karte hain, aur har ek mein ek crucial detail alag hoti hai.
strncpy(dest, src, n)
src se zyada se zyada n bytes dest mein copy karta hai.
Agar src, n se chhota ho: copy karta hai, phir baaki ko '\0' se pad karta hai .
Agar src n bytes ya zyada ho: exactly n bytes copy karta hai aur terminating '\0' add nahi karta .
Common mistake Steel-man: "
strncpy hamesha null-terminate karta hai, toh safe hai."
Kyun sahi lagta hai: n dekhne mein max length jaisa lagta hai aur naam "safe strcpy" chillata hai. Aap assume karte ho ki yeh proper C string chhod jaata hai.
Trap: jab src buffer ko exactly fill kar de (ya overflow kare), strncpy koi '\0' nahi chodta. Aapki "string" ka ab koi end nahi → agla printf/strlen garbage mein read off kar jaata hai.
Fix: hamesha khud force-terminate karo:
strncpy (dest, src, sizeof (dest) - 1 );
dest [ sizeof (dest) - 1 ] = ' \0 ' ; // guarantee termination
Worked example strncpy with a short source — "Yeh step kyun?"
char buf [ 8 ];
strncpy (buf, "hi" , sizeof (buf)); // src="hi" (2 chars)
Result bytes: 'h' 'i' '\0' '\0' '\0' '\0' '\0' '\0'.
Kyun? Source n=8 se chhota hai, toh hi\0 copy karne ke baad baaki 5 bytes zero se pad karta hai. Safe aur properly terminated — lucky hai kyunki source chhota tha.
Worked example strncpy with an oversized source — dangerous case
char buf [ 8 ];
strncpy (buf, "0123456789" , sizeof (buf)); // 10 chars into 8
Result bytes: '0' '1' '2' '3' '4' '5' '6' '7' — kahin bhi '\0' nahi!
Yeh step kyun matter karta hai: strlen(buf) ab byte 7 ke baad adjacent memory mein read karta hai. Fix line buf[7] = '\0' ise 01234567 banata hai — content truncated lekin valid string.
snprintf(dest, size, format, ...)
sprintf jaisa, lekin total zyada se zyada size bytes likhta hai, '\0' including . Yeh hamesha null-terminate karta hai (jab tak size > 0 ho). Yeh un characters ki count return karta hai jo room hota toh likhi jaati (excluding '\0').
Intuition Return value kya batata hai
Return value r needed length hai, written length nahi. Agar r ≥ size , truncation hua . Yeh gold hai: aap re-scanning ke bina overflow detect kar sakte ho.
truncated ⟺ r ≥ size
Worked example snprintf se message banana — "Yeh step kyun?"
char buf [ 8 ];
int r = snprintf (buf, sizeof (buf), "id= %d " , 12345 );
"id=12345" 8 chars hai, 9 bytes chahiye. Sirf 8 fit hain, toh buf mein "id=1234" + '\0' (7 chars + null = 8 bytes) aata hai, aur r == 8.
r == 8 kyun? Yeh woh length report karta hai jo yeh chahta tha (id=12345), toh r (8) >= size (8) truncation flag karta hai. Buf safe kyun hai? snprintf ne last byte '\0' ke liye reserve rakha — strncpy ke unlike.
Common mistake Steel-man: "
snprintf ka return value batata hai kitne bytes likhe."
Kyun sahi lagta hai: zyatatar functions wahi return karte hain jo unhone kiya. Fix: yeh woh return karta hai jo karta — r >= size use karo truncation detect karne ke liye, buffer mein bytes ki count ki jagah nahi.
strlcpy(dest, src, size)
src se size - 1 bytes tak copy karta hai, phir hamesha null-terminate karta hai (agar size > 0 ho). strlen(src) return karta hai — woh length jo yeh try karta tha copy karne ki. Agar return ≥ size, truncation hua.
Note: standard C mein nahi; BSD/macOS par available hai, aur Linux glibc mein sirf 2.38 se. Portable code hamesha iske upar rely nahi kar sakta.
strlcpy "best behaved" kyun hai
Yeh do achi behaviors combine karta hai: yeh kabhi overflow nahi karta (strncpy jaisa) aur hamesha terminate karta hai (snprintf jaisa), wasteful padding ke bina. Yeh woh function hai jo strncpy hona chahiye tha .
Worked example strlcpy — "Yeh step kyun?"
char buf [ 8 ];
size_t r = strlcpy (buf, "0123456789" , sizeof (buf));
buf = "0123456" + '\0' (7 chars + null). r == 10.
r==10 kyun? Yeh full source length report karta hai, toh r (10) >= size (8) → aapko pata hai data lost hua.
Function
Cap karta hai
Hamesha null-terminate?
Return value
Truncation check
strcpy
kuch nahi
haan (agar overflow nahi)
dest ptr
❌ unsafe
strncpy
n bytes
NAHI
dest ptr
manual
snprintf
size (\0 including)
HAAN
would-be length
r >= size
strlcpy
size-1
HAAN
strlen(src)
ret >= size
Recall Feynman: ek 12-saal ke bachche ko samjhao
Socho paani ek cup mein daal rahe ho. strcpy tab bhi daalti rehti hai jab cup bhar jaata hai — paani sab jagah gir jaata hai aur tumhara desk kharab ho jaata hai (woh crash ya hack hai). "Safe" daalney wale pehle poochte hain "cup kitna bada hai?" strncpy daalana rok deta hai lekin kabhi kabhi dhakkan lagana bhool jaata hai (koi '\0' nahi). snprintf hamesha dhakkan ke liye jagah chodta hai aur bolta hai "tumhe jo chahiye tha woh fit nahi hua." strlcpy sabse polite hai: waqt par ruk jaata hai, hamesha dhakkan lagata hai, aur dhire se batata hai ki tumhare paas actually kitna tha. Size argument woh sawaal hai "cup kitna bada hai?" — kabhi skip mat karo.
"n knot bhool jaata hai, printf aur l hamesha baandhte hain."
str**n**cpy null knot bhool sakta hai; s**n**printf aur str**l**cpy hamesha knot baandhte hain (terminate karte hain).
Safe string functions ko safe banane wala ek extra argument kya hai? Destination buffer ka size , taaki copy overflow hone se pehle ruk sake.
strncpy null-terminate kab nahi karta?Jab source length >= n (size limit) ho: exactly n bytes copy karta hai aur koi '\0' add nahi karta.
strncpy(dest, src, sizeof(dest)-1) ke baad standard fix kya hai?Manually dest[sizeof(dest)-1] = '\0'; set karo termination guarantee karne ke liye.
sizeof(dest) ki jagah zyada se zyada sizeof(dest)-1 kyun copy karte hain?Trailing '\0' ke liye ek byte reserved rehni chahiye; capacity − 1 max content hai.
Kya snprintf hamesha null-terminate karta hai? Haan, jab tak size > 0 ho, yeh hamesha terminating '\0' likhta hai.
snprintf kya return karta hai aur truncation kaise detect karte hain?Woh chars ki count return karta hai jo yeh likhta (excluding '\0'); truncation iff return >= size.
strlcpy aur strncpy mein kya fark hai?strlcpy hamesha null-terminate karta hai aur zero-pad nahi karta; size-1 par cap karta hai aur strlen(src) return karta hai.
strlcpy hamesha usable kyun nahi hai?Yeh non-standard hai (BSD origin); sab platforms par nahi — glibc ne ise sirf 2.38 mein add kiya.
char b[8]; snprintf(b,8,"id=%d",12345); — b mein kya hai aur yeh kya return karta hai?b = "id=1234" (7 chars + null); 8 return karta hai, truncation flag karta hai kyunki 8 >= 8.
Yeh functions kaunsa memory bug prevent karte hain? Buffer overflow — destination array ke end ke baad likhna.
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
Pads with nulls if src short
No null if src fills buffer