अशक्त-समाप्त स्ट्रिंग (नल्ल-टर्मिनेटेड स्ट्रिंग)
कंप्यूटर प्रोग्रामिंग में अशक्त-समाप्त स्ट्रिंग एक वर्ण स्ट्रिंग है जिसे वर्णों की सरणी डेटा संरचना के रूप में संग्रहीत किया जाता है। जिसको रिक्त स्ट्रिंग (शून्य के मान वाला एक वर्ण, जिसे इस आलेख में एनयूएल कहा जाता है) के साथ समाप्त किया जाता है। इसका वैकल्पिक नाम सी-स्ट्रिंग हैं, जो C प्रोग्रामिंग भाषा और एएससीआईआईजेड भाषा को संदर्भित करती है। हालाँकि सी (प्रोग्रामिंग भाषा) और एएससीआईआईजेड भाषा के अतिरिक्त यह अन्य एन्कोडिंग का उपयोग कर सकती है।[citation needed]
एक स्ट्रिंग की लंबाई (प्रथम) एनयूएल की खोज करके पाई जाती है। यह अपेक्षाकृत धीमी हो सकती है क्योंकि इसमें स्ट्रिंग की लंबाई के संबंध में O(n) रैखिक समय लगता है। इसका यह भी अर्थ है कि एक स्ट्रिंग मे यह रिक्त नहीं हो सकती है क्योकि यह स्ट्रिंग में ''नहीं'' अंतिम वर्ण के बाद है।
इतिहास
अशक्त-समाप्त स्ट्रिंग को पीडीपी-11 असेंबली भाषाओं के एएससीआईजेड निर्देश और पीडीपी-10 के लिए मैक्रो-10 और मैक्रो असेंबली भाषा के ASCIZ
निर्देश द्वारा निर्मित किया गया था। ये सी प्रोग्रामिंग भाषा के विकास से पहले के हैं, लेकिन इनमे स्ट्रिंग के अन्य रूपों का प्रायः उपयोग किया जाता था।
जिस समय C को जिन भाषाओं से इसे प्राप्त किया गया था उनका विकास हुआ क्योकि वे मेमोरी अपेक्षाकृत सीमित थी। इसलिए स्ट्रिंग की लंबाई को संग्रहीत करने के लिए ओवरहेड के केवल एक बाइट का उपयोग करना उपयुक्त था। उस समय का एकमात्र लोकप्रिय विकल्प, जिसे सामान्यतः "पास्कल स्ट्रिंग" कहा जाता है। एक अत्यधिक आधुनिक शब्द "लंबाई-उपसर्ग" है। यह स्ट्रिंग की लंबाई को संग्रहीत करने के लिए एक अग्रणी बाइट का उपयोग करता था। यह स्ट्रिंग को रिक्त रखने की स्वीकृति देता है और पहले से संग्रहीत स्ट्रिंग की लंबाई खोजने के लिए केवल एक मेमोरी नियंत्रण (O(1) स्थिर समय की आवश्यकता होती है, लेकिन स्ट्रिंग की लंबाई 255 वर्णों तक सीमित होती है। 8-बिट का उपयोग करने वाली मशीन पर सी विकासक डेनिस रिची ने एक स्ट्रिंग की लंबाई पर सीमा से बचने के लिए अशक्त-समाप्त स्ट्रिंग के फंक्शन का अनुसरण करना सुनिश्चित किया, क्योंकि गणना बनाए रखना उनके अनुभव में परिवर्तक का उपयोग करने से अपेक्षाकृत कम सुविधाजनक लगता था।[1][2]
इसका सीपीयू अनुदेश समूह डिज़ाइन पर अत्यधिक प्रभाव पड़ा था। 1970 और 1980 के दशक में कुछ सीपीयू, जैसे ज़िलॉग ज़ेड-80 और डीईसी वीएएक्स में लंबाई-उपसर्ग स्ट्रिंग को संभालने के लिए समर्पित निर्देश थे। हालाँकि, जैसे-जैसे रिक्त सीमित स्ट्रिंग ने कर्षण प्राप्त किया, सीपीयू निर्माताओ ने इसे ध्यान में रखना प्रारम्भ कर दिया था जैसा कि उदाहरण के लिए आईबीएम के 1992 में ईएस/9000 520 में "तार्किक स्ट्रिंग सहायता" निर्देशों और 2015 में आईबीएम जेड-13 (माइक्रोप्रोसेसर) के लिए सदिश स्ट्रिंग निर्देशों को जोड़ने के निर्णय में देखा गया था। [3]
फ्रीबीएसडी विकासक पॉल-हेनिंग काम्प ने एसीएमक्यू में लिखते हुए, 2-बाइट लंबाई पर अशक्त-समाप्त स्ट्रिंग्स की जीत को "अब तक की सबसे कीमती एक-बाइट गलती" के रूप में संदर्भित किया है।[4]
सीमाएं
प्रयुक्त करने में सरल होने के अतिरिक्त यह प्रतिनिधित्व त्रुटियों और प्रदर्शन समस्याओं से ग्रस्त रहा है।
अशक्त-समाप्त स्ट्रिंग ने ऐतिहासिक रूप से सुरक्षा समस्याएँ उत्पन्न की हैं।[5] स्ट्रिंग के बीच में प्रयुक्त किया गया NUL
इसे अप्रत्याशित रूप से छोटा कर देता है। एक सामान्य बग एनयूएल के लिए अतिरिक्त स्थान आवंटित नहीं करना था। इसलिए इसे आसन्न मेमोरी पर लिखा गया था। दूसरा यह था कि एनयूएल बिल्कुल न लिखा जाए, जिसका प्रायः परीक्षण के समय पता नहीं लगाया जा सका था क्योंकि मेमोरी के ब्लॉक में पहले से ही शून्य था। लंबाई खोजने के कारण कई प्रोग्राम किसी स्ट्रिंग को एक निश्चित आकार के डेटा बफ़र में अनुकरण करने से पहले चिंतित नहीं होते थे। जिससे यह बहुत लंबा होता है तो बफर अतिरेक हो जाता है। शून्य को संग्रहीत करने में असमर्थता के लिए आवश्यक है कि टेक्स्ट और बाइनरी डेटा को अलग-अलग रखा जाए और विभिन्न फंक्शनों द्वारा नियंत्रित किया जाए क्योकि बाद वाले डेटा को लंबाई प्रदान करने की आवश्यकता होती है। गलत फ़ंक्शन का उपयोग करने पर इसमे कोड अतिरेक और त्रुटियां हो सकती हैं।
लंबाई खोजने में गति की समस्याओं को सामान्यतः किसी अन्य ऑपरेशन के साथ जोड़कर अपेक्षाकृत कम किया जा सकता है जो कि O(n) है, जैसे कि strlcpy
में इसका परिणाम सदैव एक सहज एपीआई नहीं होता है।
अक्षरों को सांकेतिक अक्षरों में परिवर्तित करना
अशक्त-समाप्त स्ट्रिंग के लिए आवश्यक है कि एन्कोडिंग कहीं भी शून्य बाइट (0x00) का उपयोग न करे क्योकि प्रत्येक संभव एएससीआईआई या यूटीएफ-8 स्ट्रिंग को संग्रहीत करना संभव नहीं है।[6][7][8] हालाँकि, एएससीआईआई या यूटीएफ-8 के उपसमूह NUL
को छोड़कर प्रत्येक वर्ण को अशक्त-समाप्त स्ट्रिंग में संग्रहीत करना सामान्य है। कुछ सिस्टम "संशोधित यूटीएफ-8" का उपयोग करते हैं जो एनयूएल को दो गैर-शून्य बाइट्स (0xC0, 0x80) के रूप में एन्कोड करता है और इस प्रकार सभी संभावित स्ट्रिंग्स को संग्रहीत करने की स्वीकृति देता है। यूटीएफ-8 मानक द्वारा इसकी स्वीकृति नहीं है, क्योंकि यह एक लंबी एन्कोडिंग है, और इसे सुरक्षा जोखिम के रूप में देखा जाता है। इसके अतिरिक्त कुछ अन्य बाइट को स्ट्रिंग के अंत के रूप में उपयोग किया जा सकता है, जैसे 0xFE या 0xFF, जिनका उपयोग यूटीएफ-8 में नहीं किया जाता है।
यूटीएफ-16 2-बाइट पूर्णांकों का उपयोग करती है चूँकि कोई भी बाइट शून्य हो सकती है और वास्तव में प्रत्येक दूसरी बाइट जब एएससीआईआई टेक्स्ट का प्रतिनिधित्व करती है तब इसको रिक्त-सीमित बाइट स्ट्रिंग में संग्रहीत नहीं किया जा सकता है। हालाँकि कुछ भाषाएँ 16-बिट यूटीएफ-16 वर्णों की एक स्ट्रिंग प्रयुक्त करती हैं, जो 16-बिट एनयूएल (0x0000) द्वारा समाप्त होती हैं।
संशोधन
सी-स्ट्रिंग नियंत्रण को अपेक्षाकृत कम त्रुटि प्रवृत्त बनाने के लिए कई प्रयास किए गए हैं। जैसे कि strdup
और strlcpy
सुरक्षित फंक्शनों को जोड़ना है जबकि gets
जैसे असुरक्षित फंक्शनों के उपयोग को अस्वीकृत करना है। दूसरा सी-स्ट्रिंग्स के चारों ओर एक वस्तु-उन्मुख आवरण जोड़ना ताकि केवल सुरक्षित कॉल ही की जा सके। हालाँकि असुरक्षित फ़ंक्शंस को कॉल करना वैसे भी संभव होता है।
अधिकांश आधुनिक लाइब्रेरी सी-स्ट्रिंग्स को 32-बिट या बड़ी लंबाई मान वाली संरचना के साथ प्रतिस्थापित करती हैं। लंबाई-उपसर्ग स्ट्रिंग्स के लिए पहले से कहीं अधिक माना जाता था और प्रायः रूपांतरण को तीव्र करने के लिए एक और पॉइंटर, संदर्भ गणना और यहां तक कि एक एनयूएल भी जोड़ते हैं। सी-स्ट्रिंग पर वापस जाएँ क्योकि मेमोरी अब बहुत बड़ी है जैसे कि यदि प्रत्येक स्ट्रिंग में 3 या 16 से अधिक बाइट्स जोड़ना एक वास्तविक समस्या है, तो सॉफ़्टवेयर को इतने छोटे स्ट्रिंग्स से बचना होगा कि कोई अन्य भंडारण विधि और भी अधिक मेमोरी बचा सकती है। उदाहरण के लिए इतनी प्रतिलिपि स्ट्रिंग हो सकती हैं कि एक हैश तालिका अपेक्षाकृत कम मेमोरी का उपयोग करती है। उदाहरणों में सी++ मानक टेम्पलेट लाइब्रेरी std::string
Qt QString QString
, माइक्रोसॉफ्ट फाउंडेशन क्लास लाइब्रेरी CString
और Core_Foundation
से सी-आधारित कार्यान्वयन CFString
और साथ ही एप्पल द्वारा Foundation
से इसके वैकल्पिक सिबलिंग मे SString
सम्मिलित हैं। रस्सी (कंप्यूटर विज्ञान) जैसे तारों को संग्रहीत करने के लिए अधिक जटिल संरचनाओं का भी उपयोग किया जा सकता है।
यह भी देखें
संदर्भ
- ↑ Ritchie, Dennis M. (April 1993). सी भाषा का विकास. Second History of Programming Languages conference. Cambridge, MA.
- ↑ Ritchie, Dennis M. (1996). "The development of the C language". In Bergin, Jr., Thomas J.; Gibson, Jr., Richard G. (eds.). History of Programming Languages (2 ed.). New York: ACM Press. ISBN 0-201-89502-1 – via Addison-Wesley (Reading, Mass).
- ↑ IBM z/Architecture Principles of Operation
- ↑ Kamp, Poul-Henning (25 July 2011), "The Most Expensive One-byte Mistake", ACM Queue, 9 (7): 40–43, doi:10.1145/2001562.2010365, ISSN 1542-7730, S2CID 30282393
- ↑ Rain Forest Puppy (9 September 1999). "पर्ल सीजीआई समस्याएं". Phrack Magazine. artofhacking.com. 9 (55): 7. Retrieved 3 January 2016.
- ↑ "UTF-8, a transformation format of ISO 10646". Retrieved 19 September 2013.
- ↑ "Unicode/UTF-8-character table". Retrieved 13 September 2013.
- ↑ Kuhn, Markus. "UTF-8 and Unicode FAQ". Retrieved 13 September 2013.