सभी स्ट्रिंग-कॉपी / चाल परिदृश्यों में - strcat (), strncat (), strcpy (), strncpy (), इत्यादि - चीजें कुछ बेहतर ( सुरक्षित ) हो जाती हैं यदि एक युगल सरल उत्तराधिकार लागू किया जाता है:
1. हमेशा NUL-fill डेटा जोड़ने से पहले आपका बफ़र।
2. चरित्र-बफ़र्स को [SIZE + 1] के रूप में, स्थूल-स्थिरांक के साथ घोषित करें।
उदाहरण के लिए, दिया गया:
#define BUFSIZE 10
char Buffer[BUFSIZE+1] = { 0x00 }; /* The compiler NUL-fills the rest */
हम जैसे कोड का उपयोग कर सकते हैं:
memset(Buffer,0x00,sizeof(Buffer));
strncpy(Buffer,BUFSIZE,"12345678901234567890");
अपेक्षाकृत सुरक्षित रूप से। स्ट्रेट्स्की () से पहले ही समस्वरता () दिखाई देनी चाहिए, हालांकि हमने कंपाइलर-टाइम पर बफ़र को इनिशियलाइज़ किया है, क्योंकि हम नहीं जानते कि हमारे फंक्शन को कॉल करने से पहले कौन सा कचरा इसमें रखा गया था। Strncpy () कॉपी किए गए डेटा को "1234567890" पर काट देगा, और इसे NUL-term नहीं देगा । हालांकि, चूंकि हम पहले से ही BULSIZE के बजाय पूरे बफर - साइज़ोफ़ (बफ़र) को भर चुके हैं, वैसे भी NUL को समाप्त करने के लिए एक अंतिम "आउट-ऑफ-स्कोप" होने की गारंटी है, जब तक हम BUFSIZE का उपयोग करके अपने कार्यों को बाधित नहीं करते हैं आकार के बजाय स्थिर (बफर)।
स्निपर () के लिए बफर और BUFSIZE इसी तरह ठीक काम करते हैं:
memset(Buffer,0x00,sizeof(Buffer));
if(snprintf(Buffer,BUFIZE,"Data: %s","Too much data") > BUFSIZE) {
/* Do some error-handling */
} /* If using MFC, you need if(... < 0), instead */
हालांकि स्निप्रफ () विशेष रूप से केवल BUFIZE-1 अक्षर लिखते हैं, इसके बाद NUL, यह सुरक्षित रूप से काम करता है। इसलिए हम बफ़र के अंत में एक बाहरी एनयूएल बाइट को "बर्बाद" करते हैं ... हम बफर-अतिप्रवाह और असंबद्ध स्ट्रिंग स्थितियों दोनों को रोकते हैं, एक बहुत छोटी स्मृति-लागत के लिए।
Strcat () और strncat () पर मेरी कॉल अधिक हार्ड-लाइन है: उनका उपयोग न करें। स्ट्रैकट () को सुरक्षित रूप से उपयोग करना मुश्किल है, और स्ट्रेंकैट के लिए एपीआई () इतना जवाबी-सहज है कि इसे ठीक से उपयोग करने के लिए आवश्यक प्रयास किसी भी लाभ को उपेक्षित करता है। मैं निम्नलिखित ड्रॉप-इन का प्रस्ताव करता हूं:
#define strncat(target,source,bufsize) snprintf(target,source,"%s%s",target,source)
यह एक स्ट्रैट () ड्रॉप-इन बनाने के लिए आकर्षक है, लेकिन एक अच्छा विचार नहीं है:
#define strcat(target,source) snprintf(target,sizeof(target),"%s%s",target,source)
क्योंकि टार्गेट एक पॉइंटर हो सकता है (इस प्रकार sizeof () हमारे पास आवश्यक जानकारी नहीं देता है)। मेरे पास आपके कोड में strcat () के उदाहरणों के लिए एक अच्छा "सार्वभौमिक" समाधान नहीं है।
एक समस्या जिसे मैं अक्सर "strFunc () - जागरूक" प्रोग्रामर से सामना करता हूं, वह स्ट्रैलेन () का उपयोग करके बफर-ओवरफ्लो से बचाने का प्रयास है। यह ठीक है अगर सामग्री एनयूएल-समाप्त होने की गारंटी है। अन्यथा, स्ट्रैलेन () स्वयं एक बफर-ओवररन त्रुटि (आमतौर पर एक विभाजन उल्लंघन या अन्य कोर-डंप स्थिति के लिए अग्रणी) का कारण बन सकता है, इससे पहले कि आप "समस्याग्रस्त" कोड तक पहुंचने से पहले आप की रक्षा करने की कोशिश कर रहे हैं।