5.1.21 · D5 · HinglishC Programming

Question bankSafe alternatives — strncpy, snprintf, strlcpy

2,502 words11 min read↑ Read in English

5.1.21 · D5 · Coding › C Programming › Safe alternatives — strncpy, snprintf, strlcpy


Pehle, woh words jinpe poora page tikaa hai

Koi bhi trap samajhne se pehle, teen names pakke hone chahiye. Neeche ke trap questions inhe baar baar use karte hain, isliye inhe ek baar, saaf tarike se, ek picture ke saath define karte hain — is point se pehle kabhi use nahi kiye.

Neeche ki figure woh mental model hai jis par har trap return karta hai — byte-cells ki ek row, buffer ke end par ek red boundary, aur jahan '\0' ka lid hona chahiye.

Figure — Safe alternatives — strncpy, snprintf, strlcpy

Aur yeh doosri figure hai side-by-side buffer walkthrough: wahi source "01234567" (exactly 8 characters) ek 8-byte buffer mein teeno functions dwara daala gaya, taaki tum dekh sako kaun lid bhoolta hai, kaun truncate karta hai, aur kaun pad karta hai.

Figure — Safe alternatives — strncpy, snprintf, strlcpy
Recall Ek nazar mein summary table
Function Jo ceiling use karta hai Text room Hamesha '\0' add karta hai? Return value Negative return?
strncpy n bytes n (koi reserve nahi) Nahi dest pointer kabhi nahi
snprintf size (incl. '\0') size - 1 Haan (agar size>0) would-be length haan, encoding error par
strlcpy size (incl. '\0') size - 1 Haan (agar size>0) strlen(src) kabhi nahi

True ya false — justify karo

strncpy bas ek safer strcpy hai jisme length cap hai aur koi extra care ki zaroorat nahi.
False. Yeh byte count ko n par cap karta hai, lekin jab source n bytes ya zyada lamba ho (saare n slots bhar de) toh woh koi '\0' nahi likhta, ek non-terminated buffer chod deta hai jise baad mein padhne wale walk off kar dete hain — tumhe khud terminate karna hoga.
snprintf hamesha ek valid, null-terminated C string chod jaata hai (maana jaaye size > 0 hai).
True. Woh source kitna bhi lamba ho, final byte '\0' ke liye reserve karta hai, isliye result hamesha ek proper C string hoti hai — shayad truncated, lekin hamesha readable.
strlcpy aur strncpy same arguments ke liye identical buffer contents produce karte hain.
False. Ek chhote source ke liye strncpy har remaining byte ko zero-pad karta hai; strlcpy ek '\0' likhta hai aur ruk jaata hai. Aur jab source overflow kare, strncpy koi terminator nahi chod ta jabki strlcpy hamesha terminate karta hai.
Agar snprintf size se kam value return kare, toh poori string bina truncation ke fit ho gayi.
Sirf tab jab return non-negative ho. Ek return r jisme 0 <= r < size ho matlab hai sab kuch plus terminator fit ho gaya. Lekin ek negative return ek encoding/output error signal karta hai, "fit ho gaya" nahi — isliye pehle hamesha r >= 0 check karo, phir r < size.
strlcpy standard C ka part hai, isliye tum ise kisi bhi portable program mein use kar sakte ho.
False. Yeh ek BSD extension hai, C standard mein nahi hai; glibc ne ise sirf version 2.38 mein add kiya, isliye portable code iske hamesha available hone par rely nahi kar sakta.
char buf[8]; strncpy(buf, "hi", sizeof(buf)); ek unterminated buffer chod ta hai.
False. Source "hi" (2 chars) n = 8 se chhota hai, isliye strncpy h i \0 copy karta hai phir baaki sab zeros se pad karta hai — buffer yahan fully terminated hai, chhote source ki wajah se.
sizeof(dest) aur strlen(dest) same number dete hain, isliye cap ke liye dono kaam karte hain.
False. sizeof array ki compile-time capacity hai (constant); strlen '\0' se pehle ke characters ki run-time count hai. Safe capping ke liye tumhe capacity chahiye, yaani sizeof. Dekho sizeof vs strlen.
String ko safely truncate karna hamesha theek hai kyunki "no crash" ka matlab "no bug" hai.
False. Silent truncation logic corrupt kar sakti hai — ek truncated filename, URL, ya command galat jagah point kar sakta hai. Safe ka matlab hai koi memory corruption nahi; truncated value ki correctness ek alag concern hai jise tum abhi bhi return value ke zariye check karo.
snprintf kabhi negative number return nahi kar sakta, isliye r >= size akela ek complete truncation test hai.
False. Ek encoding error par (jaise ek invalid multibyte conversion) snprintf ek negative value return karta hai. Kyunki size_t/int comparisons mislead kar sakte hain, failure ke liye r < 0 se guard karo pehle r >= size truncation ke liye use karne se pehle.

Error dhundho

strncpy(dest, src, sizeof(src)); — size argument mein kya galat hai?
Yeh source ke size se cap karta hai, destination ke nahi. Agar src ek pointer hai, toh sizeof(src) pointer ka size hai (aksar 8), jo is baat se koi rishta nahi rakhta ki dest kitne bytes hold kar sakta hai — yeh abhi bhi dest overflow kar sakta hai. Hamesha sizeof(dest) se cap karo.
strncpy(dest, src, sizeof(dest)); dest[strlen(dest)] = '\0'; — fix kyun broken hai?
Agar strncpy ne terminate nahi kiya, toh strlen(dest) buffer ke baad padh jaata hai '\0' dhundhne ke liye, isliye woh index jo return karta hai already garbage hai. Sahi fix known last slot ko index karta hai: dest[sizeof(dest)-1] = '\0';.
if (snprintf(buf, size, ...) > 0) { /* assume no truncation */ } — logic bug kya hai?
Positive return sirf yeh batata hai ki characters format hue, yeh nahi ki woh fit hue. Truncation return >= size se detect hota hai (yeh check karne ke baad ki return >= 0), na ki "return positive hai" se. Ek bada positive return bilkul wahi overflow signal hai.
char buf[8]; snprintf(buf, sizeof(src), "%s", src); — kaun sa size galat hai?
size destination ki capacity honi chahiye, sizeof(buf). Source size paasna snprintf ko ek 8-byte buffer mein sizeof(src) bytes tak likhne deta hai, poori baat ka fayda khatam kar deta hai. Dekho Buffer overflow and stack smashing.
strncpy(dest, src, sizeof(dest) - 1); koi follow-up line nahi — author ne kya bhool gaya?
Manual terminator dest[sizeof(dest)-1] = '\0';. Jab source kaafi lamba ho tab strncpy abhi bhi '\0' add nahi kar sakta, isliye index sizeof(dest)-1 non-null ho sakta hai aur string unterminated ho jaati hai.
char *p = malloc(8); strlcpy(p, src, 8); phir baad mein p ko old glibc ke saath banaye Linux box par use karna — kya toot ta hai?
glibc 2.38 se pehle strlcpy exist hi nahi karta, isliye program link hone mein fail karta hai ya silently ek alag symbol use karta hai. Portability, runtime logic nahi, yahan trap hai.
size_t r = strlcpy(buf, src, 0); — kya yeh safe hai?
size == 0 ke saath function bilkul kuch nahi likhta, isliye buf ko null-terminate nahi karta. buf mein jo bhi pehle se garbage tha woh ek unterminated string reh jaata hai; buf ko string ki tarah treat karne se pehle zero size se guard karo. (Yaad raho size unsigned size_t hai, isliye size - 1 kabhi mat compute karo bina pehle size > 0 check kiye.)
int r = snprintf(buf, size, ...); if ((size_t)r < size) use(buf);r negative ho toh subtle bug?
Negative r ko size_t mein cast karne par woh ek bada unsigned number ban jaata hai, isliye (size_t)r < size false ho jaata hai aur error "truncated" branch mein slip kar jaata hai error branch ki jagah. Pehle r < 0 ko signed int ke roop mein test karo.

Why questions

Copy ko sizeof(dest) - 1 par cap karna (na ki sizeof(dest)) kyun matter karta hai?
k visible characters wali string ko k+1 bytes chahiye trailing '\0' ki wajah se. End mein us terminator ke liye ek slot reserve karna exactly woh "−1" hai, isliye content kabhi us jagah ko nahi kha sakta jo null ko chahiye.
snprintf written length ki jagah would-be length kyun return karta hai?
Taaki ek single number tumhe result size aur yeh dono bataye ki woh fit hua: ise size se compare karo. Agar woh sirf jo fit hua woh return karta, tum kabhi "exactly full" aur "overflowed" mein fark nahi kar paate, truncation signal kho jaata.
snprintf ka return negativity ke liye size se compare karne se pehle kyun check karna chahiye?
Kyunki output/encoding errors negative value return karte hain; us value ko compare karna (especially unsigned cast ke baad) "bada, toh truncated" pad sakta hai aur ek real failure chhupa sakta hai. Negative matlab hai format hi nahi ho paya, truncation se alag ek problem.
strncpy ka zero-padding wasteful kyun maana jaata hai?
Ek bade buffer mein chhote source ke liye yeh har remaining byte mein '\0' likhta hai, jo buffer size ke proportional extra kaam hai — pointless jab ek terminator kaam karta, jaise strlcpy karta hai.
Ek unterminated buffer copy se kaafi door crash kyun cause kar sakta hai?
Baad ka code jaise printf("%s") ya strlen adjacent memory mein randomly zero byte milne tak padhta rehta hai. Failure wahin dikhti hai jahan woh read hota hai — copy par nahi — bug ko trace karna mushkil ho jaata hai.
Destination size in functions ke liye "whole game" kyun hai?
Yeh woh ek piece of information hai jo unsafe functions ke paas kabhi nahi thi, isliye woh ruk nahi sakte the. Unhe capacity dena unhe time par halt karne deta hai; har safety property us single argument se flow karti hai.
strlcpy strlen(src) kyun return karta hai na ki actually copy kiye gaye bytes kitne hain?
Poora intended length report karna tumhe return >= size se truncation detect karne deta hai, snprintf ko mirror karte hue. Ek copied-byte count hamesha < size hota, yeh fact chhupaata ki data drop hua.

Edge cases

char buf[8]; strncpy(buf, "01234567", 8); — kitne characters aur kya yeh terminated hai?
Source exactly 8 chars = ceiling n hai, isliye saare 8 bytes 0..7 se bhar jaate hain aur koi room nahi aur koi '\0' nahi — ek unterminated 8-byte buffer, classic trap case (figure s02 ki middle row dekho).
char buf[8]; snprintf(buf, 8, "%s", "01234567"); — same source, strncpy case se kya alag hai?
snprintf terminator ke liye last byte reserve karta hai, isliye buf ban jaata hai "0123456\0" (7 chars) aur return 8 hai. Yeh truncated hai lekin safe aur terminated hai — strncpy version ke unlike (figure s02 ki bottom row).
snprintf(buf, 1, "%s", "hi");buf mein kya end up hota hai?
size == 1 ke saath single byte '\0' ke liye use hoti hai, isliye buf ek empty lekin valid string "" hai. Return abhi bhi 2 hai (would-be length), truncation flag karta hai.
snprintf(NULL, 0, "id=%d", 12345); — kya yeh ek bug hai, aur return kya hai?
Bug nahi; yeh ek standard idiom hai. size == 0 ke saath kuch nahi likha jaata (isliye NULL theek hai) aur yeh 8 return karta hai, woh length jo chahiye — tumhe real call se pehle exactly sahi buffer allocate karne deta hai.
snprintf format ke beech mein encoding error hit kare — woh kya return karta hai aur buf mein kya hai?
Woh ek negative value return karta hai aur buffer contents indeterminate/incomplete hain. Isliye failure (r < 0) truncation (r >= size) se ek alag branch hai.
strncpy(dest, src, 0); — kya hota hai?
Woh zero bytes copy karta hai aur koi terminator nahi add karta, isliye dest untouched reh jaata hai. Agar dest mein garbage tha, woh abhi bhi ek unterminated string hai — zero ceiling ek safe no-op nahi hai.
strncpy jab src aur dest overlap karte hain — kya yeh defined hai?
Nahi. Yeh functions non-overlapping memory require karte hain; overlapping regions undefined behavior hain, isliye results unpredictable hain. Dekho Memory safety and undefined behavior.
Empty source strlcpy(buf, "", 8);buf mein kya hai aur return kya hai?
buf[0] ko '\0' set kiya jaata hai (ek empty valid string) aur return 0 hai, kyunki strlen("") 0 hai. Koi truncation nahi, cleanly terminated.
char buf[8]; snprintf(buf, sizeof(buf), "id=%d", 12345);buf ki value aur return?
"id=12345" ko 9 bytes chahiye lekin sirf 8 fit hote hain, isliye buf mein "id=1234" (7 chars + '\0') hai aur return 8 hai; kyunki 8 >= 8, truncation flag ho jaata hai.

Connections