क्या एक उत्तेजक सवाल!
यहां तक कि इस थ्रेड में प्रतिक्रियाओं और टिप्पणियों की सरसरी स्कैनिंग से यह पता चलेगा कि आपकी प्रतीत होने वाली सरल और सीधे आगे की क्वेरी कैसे भावनात्मक हो जाती है।
इसमें आश्चर्य नहीं होना चाहिए।
निस्संदेह, संकेत की अवधारणा और उपयोग के बारे में गलतफहमी सामान्य रूप से प्रोग्रामिंग में गंभीर विफलताओं का एक प्रमुख कारण है ।
इस वास्तविकता को मान्यता विशेष रूप से संबोधित करने के लिए डिज़ाइन की गई भाषाओं की सर्वव्यापकता में स्पष्ट रूप से दिखाई देती है, और अधिमानतः चुनौतियों का सामना करने से पूरी तरह से बचने के लिए। C ++ और सी, जावा और उसके संबंधों के अन्य डेरिवेटिव, पायथन और अन्य लिपियों के बारे में सोचें - केवल अधिक प्रमुख और प्रचलित लोगों के रूप में, और कम या ज्यादा इस मुद्दे से निपटने की गंभीरता में आदेश दिया।
अंतर्निहित सिद्धांतों की गहरी समझ विकसित करना, इसलिए प्रत्येक व्यक्ति के लिए प्रासंगिक होना चाहिए जो प्रोग्रामिंग में उत्कृष्टता की इच्छा रखता है - विशेष रूप से सिस्टम स्तर पर ।
मुझे लगता है कि यह वही है जो आपके शिक्षक को प्रदर्शित करने का मतलब है।
और सी की प्रकृति इस अन्वेषण के लिए एक सुविधाजनक वाहन बनाती है। विधानसभा की तुलना में कम स्पष्ट रूप से - हालांकि शायद अधिक आसानी से समझ में आता है - और अभी भी निष्पादन पर्यावरण के गहन अमूर्तता पर आधारित भाषाओं की तुलना में अधिक स्पष्ट रूप से।
प्रोग्रामर के इरादों के निर्धारक अनुवाद को सुविधाजनक बनाने के लिए बनाया गया है , जो निर्देश दे सकता है कि मशीनें एक प्रणाली स्तर की भाषा हैं। उच्च-स्तरीय के रूप में वर्गीकृत करते हुए, यह वास्तव में 'मध्यम' श्रेणी में आता है; लेकिन चूंकि ऐसा कोई भी मौजूद नहीं है, इसलिए 'प्रणाली' के पदनाम को पर्याप्त करना होगा।
यह विशेषता है कि यह एक बनाने के लिए काफी हद तक जिम्मेदार है पसंद की भाषा के लिए डिवाइस ड्राइवर , ऑपरेटिंग सिस्टम कोड, और एम्बेडेड कार्यान्वयन। इसके अलावा, अनुप्रयोगों में एक योग्य इष्ट विकल्प जहां इष्टतम दक्षता सर्वोपरि है; जहां अस्तित्व और विलुप्त होने के बीच अंतर का मतलब है, और इसलिए एक लक्जरी के विपरीत एक आवश्यकता है । ऐसे उदाहरणों में, पोर्टेबिलिटी की आकर्षक सुविधा अपने सभी आकर्षण खो देती है, और कम से कम आम भाजक के अभाव-चमक प्रदर्शन के लिए चयन एक अकल्पनीय हानिकारक विकल्प बन जाता है।
C क्या बनाता है - और इसके कुछ व्युत्पन्न - काफी विशेष है, यह है कि यह अपने उपयोगकर्ताओं को पूर्ण नियंत्रण की अनुमति देता है - जब उनकी इच्छा होती है - उन पर संबंधित जिम्मेदारियों को लागू किए बिना जब वे नहीं करते हैं। फिर भी, यह कभी नहीं की तुलना में अधिक प्रदान करता है insulations की सबसे पतला से मशीन , किस समुचित उपयोग की मांग मांग समझ की अवधारणा के संकेत दिए गए ।
संक्षेप में, आपके प्रश्न का उत्तर बेहद सरल और संतोषजनक रूप से मीठा है - आपके संदेह की पुष्टि में। बशर्ते , कि इस कथन में प्रत्येक अवधारणा को अपेक्षित महत्व दिया जाए:
- पॉइंटर्स की जांच, तुलना और हेरफेर करने के कार्य हमेशा और आवश्यक रूप से मान्य होते हैं, जबकि परिणाम से प्राप्त निष्कर्ष निहित मूल्यों की वैधता पर निर्भर करता है, और इस तरह की आवश्यकता नहीं है।
पूर्व दोनों हमेशा सुरक्षित और संभावित रूप से उचित होते हैं , जबकि बाद वाला कभी भी उचित हो सकता है हो जब इसे सुरक्षित के रूप में स्थापित किया गया हो । हैरानी की बात है - कुछ करने के लिए - तो बाद की वैधता की स्थापना पर निर्भर करता है और पूर्व की मांग करता है ।
बेशक, भ्रम का हिस्सा एक संकेतक के सिद्धांत के भीतर अंतर्निहित पुनरावृत्ति के प्रभाव से उत्पन्न होता है - और पता से सामग्री को अलग करने में उत्पन्न चुनौतियां।
आपने बहुत सही ढंग से सर्मिपत किया है,
मुझे यह सोचने के लिए प्रेरित किया जा रहा है कि किसी भी पॉइंटर की तुलना किसी अन्य पॉइंटर के साथ की जा सकती है, भले ही वे व्यक्तिगत रूप से इंगित करें। इसके अलावा, मुझे लगता है कि दो बिंदुओं के बीच सूचक अंकगणित ठीक है, कोई फर्क नहीं पड़ता कि वे व्यक्तिगत रूप से कहां इंगित करते हैं क्योंकि अंकगणित सिर्फ मेमोरी का उपयोग करके पॉइंटर्स स्टोर को संबोधित करता है।
और कई योगदानकर्ताओं ने पुष्टि की है: संकेत केवल संख्याएं हैं। कभी-कभी कुछ जटिल संख्याओं के करीब होते हैं, लेकिन फिर भी संख्याओं से अधिक नहीं।
मनोरंजक संयोजन जिसमें यह विवाद यहाँ प्राप्त हुआ है, प्रोग्रामिंग की तुलना में मानव प्रकृति के बारे में अधिक बताता है, लेकिन ध्यान देने योग्य और विस्तार के योग्य है। शायद हम बाद में ऐसा करेंगे ...
जैसा कि एक टिप्पणी इशारा करना शुरू करती है; यह सब भ्रम और विवशता इस बात से उत्पन्न होती है कि जो सुरक्षित है , उससे मान्य है , लेकिन यह एक निरीक्षण है। हमें यह भी भेद करना चाहिए कि क्या कार्यात्मक है और क्या विश्वसनीय है , क्या व्यावहारिक है और क्या उचित हो सकता है , और आगे अभी भी: किसी विशेष परिस्थिति में क्या उचित है में क्या उचित है जो अधिक सामान्य अर्थों में उचित हो सकता है । उल्लेख नहीं करना; अनुरूपता और औचित्य के बीच अंतर ।
उस छोर की ओर, हमें सबसे पहले सराहना की जरूरत है ठीक कि एक पॉइंटर क्या है ।
- आपने अवधारणा पर एक मजबूत पकड़ का प्रदर्शन किया है, और कुछ अन्य लोगों की तरह इन दृष्टांतों को सरसरी तौर पर सरलीकृत किया जा सकता है, लेकिन यहाँ स्पष्ट भ्रम का स्तर स्पष्टीकरण में ऐसी सरलता की मांग करता है।
जैसा कि कई ने बताया है: पॉइंटर शब्द केवल एक विशेष नाम है जो कि बस एक है इंडेक्स के, और इस प्रकार यह किसी भी अन्य संख्या से अधिक नहीं है।
यह इस तथ्य को ध्यान में रखते हुए पहले से ही स्पष्ट होना चाहिए कि सभी समकालीन मुख्यधारा के कंप्यूटर बाइनरी मशीन हैं जो आवश्यक रूप से विशेष रूप से और नंबरों पर काम करते हैं । क्वांटम कंप्यूटिंग में बदलाव हो सकता है, लेकिन यह बहुत अधिक संभावना नहीं है, और यह उम्र का नहीं आया है।
तकनीकी रूप से, जैसा कि आपने उल्लेख किया है, संकेत अधिक सटीक पते हैं ; एक स्पष्ट अंतर्दृष्टि जो स्वाभाविक रूप से घरों के 'पतों', या एक सड़क पर भूखंडों के साथ उन्हें सहसंबद्ध करने के पुरस्कृत सादृश्य का परिचय देती है।
में फ्लैट मेमोरी मॉडल में: संपूर्ण सिस्टम मेमोरी एक एकल, रैखिक अनुक्रम में आयोजित की जाती है: शहर के सभी घर एक ही सड़क पर स्थित हैं, और प्रत्येक घर की विशिष्ट पहचान अकेले इसकी संख्या से है। प्रसन्नतापूर्वक सरल।
में खंडित योजनाओं: गिने सड़कों का एक सौपानिक संगठन गिने घरों ताकि समग्र पतों के लिए आवश्यक हैं की है कि इसके बाद के संस्करण शुरू की है।
- कुछ कार्यान्वयन अभी भी अधिक जटिल हैं, और विशिष्ट 'सड़कों' की समग्रता को एक सन्निहित अनुक्रम के योग की आवश्यकता नहीं है , लेकिन इनमें से कोई भी अंतर्निहित के बारे में कुछ भी नहीं बदलता है।
- हम आवश्यक रूप से इस तरह के हर पदानुक्रमित लिंक को एक सपाट संगठन में वापस करने में सक्षम हैं। संगठन जितना अधिक जटिल होगा, उतने अधिक हुप्स के माध्यम से हमें ऐसा करना होगा , लेकिन यह संभव होना चाहिए। वास्तव में, यह x86 पर 'वास्तविक मोड' पर भी लागू होता है।
- अन्यथा स्थानों के लिंक की मैपिंग बायजेक्टिव नहीं होगी , क्योंकि विश्वसनीय निष्पादन - सिस्टम स्तर पर - मांग करता है कि यह जरूरी है।
- कई पते विलक्षण स्मृति स्थानों के लिए मैप नहीं होने चाहिए , और
- एकवचन पते को कई मेमोरी स्थानों पर कभी भी मैप नहीं करना चाहिए ।
हमें आगे मोड़ पर लाना जो इस तरह के एक आकर्षक जटिल उलझन में पहेली को बदल देता है । ऊपर, यह सुझाव देना समीचीन था कि संकेत सरलता और स्पष्टता के लिए पते हैं । बेशक, यह सही नहीं है। एक सूचक है नहीं एक पते; एक सूचक एक पते का संदर्भ है , इसमें एक पता होता है । लिफाफे की तरह घर के लिए एक संदर्भ। इस पर विचार करने से आपको यह पता चल सकता है कि अवधारणा में निहित पुनरावृत्ति के सुझाव के साथ क्या था। फिर भी; हमारे पास केवल इतने सारे शब्द हैं, और पते के संदर्भों के बारे में बात कर रहे हैंऔर इस तरह, जल्द ही एक अवैध ऑप-कोड अपवाद पर अधिकांश दिमागों को रोक देता है । और अधिकांश भाग के लिए, इरादे को संदर्भ से आसानी से प्राप्त किया जाता है, इसलिए हमें सड़क पर वापस आना चाहिए।
हमारे इस काल्पनिक शहर में डाक कर्मचारी बहुत हैं जैसे हम 'वास्तविक' दुनिया में पाते हैं। जब आप बात करते हैं या किसी अमान्य पते के बारे में पूछताछ करते हैं, तो किसी को भी नुकसान होने की संभावना नहीं है , लेकिन जब आप उनसे उस जानकारी पर कार्य करने के लिए कहेंगे, तो हर आखिरी समय गंजा होगा ।
मान लीजिए हमारी विलक्षण सड़क पर केवल 20 घर हैं। आगे यह दिखावा करते हैं कि कुछ पथभ्रष्ट, या डिस्लेक्सिक आत्मा ने एक पत्र को निर्देशित किया है, एक बहुत ही महत्वपूर्ण, 71 नंबर पर। अब, हम अपने वाहक फ्रैंक से पूछ सकते हैं कि क्या ऐसा कोई पता है, और वह बस और शांति से रिपोर्ट करेगा: नहीं । हम उससे यह अनुमान लगाने की भी उम्मीद कर सकते हैं कि अगर यह मौजूद था तो सड़क के बाहर यह स्थान कितना झूठ होगा : अंत से लगभग 2.5 गुना अधिक। इस में से कोई भी उसे किसी भी तरह का अतिश्योक्ति नहीं करेगा। हालाँकि, अगर हम उसे यह पत्र देने के लिए कहें , या उस स्थान से कोई आइटम लेने के लिए कहें , तो वह अपनी नाराजगी के बारे में काफी स्पष्ट हो सकता है , और मना कर सकता है अनुपालन से कर सकता है।
पॉइंटर्स सिर्फ एड्रेस हैं, और एड्रेस सिर्फ नंबर हैं।
निम्नलिखित के उत्पादन को सत्यापित करें:
void foo( void *p ) {
printf(“%p\t%zu\t%d\n”, p, (size_t)p, p == (size_t)p);
}
इसे जितने चाहें उतने पॉइंट पर बुलाएं, मान्य या नहीं। कृपया है अपने निष्कर्षों पोस्ट अगर यह आपके मंच पर विफल रहता है, या अपने (समकालीन) संकलक शिकायत।
अब, क्योंकि संकेत दिए गए हैं बस संख्या है, यह अनिवार्य रूप से उनकी तुलना करने के वैध है। एक मायने में यह वही है जो आपके शिक्षक का प्रदर्शन है। निम्नलिखित सभी कथन पूरी तरह से मान्य हैं - और उचित! - C, और जब संकलित समस्याओं का सामना किए बिना चलेगा , भले ही न तो पॉइंटर को आरंभीकृत करने की आवश्यकता है और वे जो मान रखते हैं, वे अपरिभाषित हो सकते हैं :
- हम केवल स्पष्टता के लिए
result
स्पष्ट रूप से गणना कर रहे हैं , और इसे संकलित करने के लिए मजबूर करने के लिए छपाई कर रहे हैं कि क्या अन्यथा अनावश्यक, मृत कोड होगा।
void foo( size_t *a, size_t *b ) {
size_t result;
result = (size_t)a;
printf(“%zu\n”, result);
result = a == b;
printf(“%zu\n”, result);
result = a < b;
printf(“%zu\n”, result);
result = a - b;
printf(“%zu\n”, result);
}
बेशक, यह कार्यक्रम बीमार है, जब परीक्षण के बिंदु पर या तो एक या बी अपरिभाषित है (पढ़ें: ठीक से शुरू नहीं किया गया है ), लेकिन यह हमारी चर्चा के इस हिस्से के लिए पूरी तरह अप्रासंगिक है। ये स्निपेट भी निम्नलिखित बयानों के रूप में, कर रहे हैं गारंटी - द्वारा 'मानक' - करने के लिए संकलन और चलाने दोषरहित, के होते हुए भी में किसी भी शामिल सूचक की -validity।
समस्याएँ तभी उत्पन्न होती हैं जब एक अमान्य सूचक को निष्क्रिय कर दिया जाता है । जब हम फ्रैंक को अमान्य, गैर-मौजूद पते पर लेने या देने के लिए कहते हैं।
किसी भी मनमानी सूचक को देखते हुए:
int *p;
हालांकि इस कथन को संकलित और चलाना चाहिए:
printf(“%p”, p);
... जैसा कि यह होना चाहिए:
size_t foo( int *p ) { return (size_t)p; }
... दो के बाद, विपरीत, अभी भी आसानी से संकलन होगा, लेकिन असफल निष्पादन में जब तक सूचक है वैध - जिसके द्वारा हम यहां केवल मतलब यह है कि एक पता जिस पर वर्तमान आवेदन पहुंच प्रदान की गई संदर्भ देता है :
printf(“%p”, *p);
size_t foo( int *p ) { return *p; }
परिवर्तन कितना सूक्ष्म? जो - सूचक के मूल्य के बीच का अंतर में अंतर झूठ है कि संख्या में घर से: पता, और सामग्री के मूल्य। कोई समस्या तब तक नहीं उठती जब तक कि पॉइंटर को डिफाइन नहीं किया जाता ; जब तक उस पते तक पहुंचने का प्रयास नहीं किया जाता है, जिससे वह लिंक करता है। सड़क के खिंचाव से परे पैकेज देने या लेने की कोशिश में ...
विस्तार से, एक ही सिद्धांत आवश्यक रूप से अधिक जटिल उदाहरणों पर लागू होता है, जिसमें आवश्यक वैधता स्थापित करने के लिए पूर्वोक्त आवश्यकता शामिल है :
int* validate( int *p, int *head, int *tail ) {
return p >= head && p <= tail ? p : NULL;
}
संबंधपरक तुलना और अंकगणित समतुल्यता के परीक्षण के लिए समान उपयोगिता प्रदान करते हैं, और समान रूप से मान्य हैं - सिद्धांत रूप में। हालाँकि , इस तरह की गणना के परिणाम क्या संकेत देते हैं , यह पूरी तरह से एक अलग मामला है - और ठीक आपके द्वारा शामिल किए गए उद्धरणों द्वारा संबोधित किया गया मुद्दा।
सी में, एक सरणी एक सन्निहित बफर है, स्मृति स्थानों की एक निर्बाध रैखिक श्रृंखला है। तुलना और अंकगणित ने संकेत दिया कि ऐसी विलक्षण श्रृंखला के भीतर संदर्भ स्थान स्वाभाविक रूप से हैं, और स्पष्ट रूप से दोनों एक दूसरे के संबंध में सार्थक हैं, और इस 'सरणी' के लिए (जिसे बस आधार द्वारा पहचाना जाता है)। संक्षेप में यही बात हर ब्लॉक पर लागू होती है malloc
, या sbrk
। क्योंकि ये संबंध अंतर्निहित हैं , संकलक उनके बीच वैध संबंध स्थापित करने में सक्षम है, और इसलिए यह आश्वस्त हो सकता है कि गणना अनुमानित उत्तर प्रदान करेगी।
अलग-अलग ब्लॉकों या सरणियों को संदर्भित करने वाले बिंदुओं पर समान जिमनास्टिक प्रदर्शन करना इस तरह की अंतर्निहित , और स्पष्ट उपयोगिता की पेशकश नहीं करता है । एक पल में जो भी संबंध मौजूद होता है, वह अधिक से अधिक एक वास्तविक स्थान द्वारा अमान्य हो सकता है, जो कि परिवर्तन की अत्यधिक संभावना है, यहां तक कि उलटा भी हो सकता है। इस तरह के मामलों में कंपाइलर पिछली स्थिति में जो आत्मविश्वास था उसे स्थापित करने के लिए आवश्यक जानकारी प्राप्त करने में असमर्थ है।
आप , हालांकि, प्रोग्रामर के रूप में,ऐसा ज्ञान हो सकता है! और कुछ उदाहरणों में इसका फायदा उठाने के लिए बाध्य किया जाता है।
वहाँ हैं , इसलिए, जिन परिस्थितियों में भी पूरी तरह से वैध और पूरी तरह से उचित।
वास्तव में, यह वही है जो malloc
खुद को आंतरिक रूप से करना पड़ता है जब समय आवर्ती ब्लॉकों को विलय करने की कोशिश करता है - विशाल बहुमत पर। ऑपरेटिंग सिस्टम आवंटनकर्ता के लिए भी यही सच है, जैसे कि पीछे sbrk
; यदि अधिक स्पष्ट रूप से , अक्सर , अधिक विषम संस्थाओं पर, अधिक गंभीर रूप से - और प्रासंगिक उन प्लेटफार्मों पर भी जहां यह malloc
नहीं हो सकता है। और C में से कितने नहीं लिखे गए हैं?
किसी कार्रवाई की वैधता, सुरक्षा और सफलता अनिवार्य रूप से अंतर्दृष्टि के स्तर का परिणाम है, जिस पर यह आधार और लागू होता है।
आपके द्वारा पेश किए गए उद्धरणों में, कार्निघन और रिची एक निकट से संबंधित को संबोधित कर रहे हैं, लेकिन फिर भी अलग मुद्दा है। वे कर रहे हैं परिभाषित करने सीमाओं की भाषा , और बताया गया हो कि आप कम से कम संभावित गलत निर्माणों पता लगाने के द्वारा आप की रक्षा के लिए संकलक की क्षमताओं का दोहन कर सकते हैं। वे लंबाई का वर्णन कर रहे हैं कि तंत्र सक्षम है - डिज़ाइन किया गया है - ताकि आप अपने प्रोग्रामिंग कार्य में सहायता के लिए जा सकें। संकलक अपने नौकर है, आप कर रहे हैं मास्टर। हालाँकि, एक बुद्धिमान गुरु वह है जो अपने विभिन्न नौकरों की क्षमताओं से परिचित है।
इस संदर्भ में, अपरिभाषित व्यवहार संभावित खतरे और नुकसान की संभावना को इंगित करने का कार्य करता है; जैसा कि हम जानते हैं कि आसन्न, अपरिवर्तनीय कयामत या दुनिया के अंत का अर्थ नहीं है। इसका सीधा सा मतलब है कि हम - 'अर्थ द कम्पाइलर' - इस बात के बारे में कोई अनुमान नहीं लगा पा रहे हैं कि यह क्या हो सकता है, या प्रतिनिधित्व कर सकता है और इसी कारण से हम इस मामले से हाथ धोना चाहते हैं। इस सुविधा के उपयोग, या गलत उपयोग के परिणामस्वरूप होने वाले किसी भी दुस्साहस के लिए हमें जवाबदेह नहीं ठहराया जाएगा ।
वास्तव में, यह बस कहता है: 'इस बिंदु से परे, काउबॉय : आप अपने दम पर हैं ...'
आपका प्रोफेसर आपसे बारीक बारीकियों को प्रदर्शित करना चाहता है।
ध्यान दें कि उन्होंने अपना उदाहरण प्रस्तुत करने में कितनी सावधानी बरती है; और यह अभी भी कितना भंगुर है। में , का पता लेकरa
p[0].p0 = &a;
संकलक को चर के लिए वास्तविक भंडारण आवंटित करने के लिए बाध्य किया जाता है, बजाय इसे एक रजिस्टर में रखने के। यह एक स्वचालित चर है, हालांकि, प्रोग्रामर का कोई नियंत्रण नहीं है कि उसे कहाँ सौंपा गया है, और इसलिए इसका पालन करने के बारे में कोई भी वैध अनुमान लगाने में असमर्थ है। इसीलिए कोड को अपेक्षित रूप से काम करने के लिए शून्य के बराबर सेट किया a
जाना चाहिए।
इस लाइन को बदलते हुए:
char a = 0;
इसके लिए:
char a = 1; // or ANY other value than 0
कार्यक्रम के व्यवहार को अपरिभाषित होने का कारण बनता है । कम से कम, पहला उत्तर अब 1 होगा; लेकिन समस्या कहीं अधिक भयावह है।
अब कोड आपदा को आमंत्रित कर रहा है।
हालांकि अभी भी पूरी तरह से वैध है और मानक के अनुरूप भी है , लेकिन अब यह बीमार है और संकलन के लिए सुनिश्चित है, विभिन्न आधारों पर निष्पादन में विफल हो सकता है। अभी के लिए देखते हैं कई समस्याओं - कोई भी जिनमें से संकलक है सक्षम करने के लिए स्वीकार करते हैं।
strcpy
के पते पर शुरू होगा a
, और इस से आगे बढ़ने के लिए उपभोग - और हस्तांतरण - बाइट के बाद बाइट, जब तक कि यह एक नल का सामना नहीं करता।
p1
सूचक बिल्कुल के एक ब्लॉक के लिए शुरू कर दिया गया है 10 बाइट्स।
अगर a
किसी ब्लॉक के अंत में रखा जाता है और इस प्रक्रिया का कोई उपयोग नहीं होता है, तो अगले पढ़ें - p0 [1] की - एक सेगफॉल्ट को हटा देगा। यह परिदृश्य है संभावना नहीं x86 आर्किटेक्चर पर है, लेकिन संभव।
यदि का पता परे क्षेत्र a
है सुलभ, कोई पठन त्रुटि हो जाएगा, लेकिन कार्यक्रम अभी भी दुर्भाग्य से सहेजा नहीं गया है।
यदि एक शून्य बाइट के पते पर शुरू होने वाले दस के भीतर होता है a
, तो यह अभी भी जीवित रह सकता है , इसके लिए strcpy
बंद हो जाएगा और कम से कम हम एक लेखन उल्लंघन नहीं भुगतेंगे।
यदि यह एमिस पढ़ने के लिए दोषपूर्ण नहीं है , लेकिन 10 के इस अवधि में कोई शून्य बाइट नहीं होता है, strcpy
तो जारी रहेगा और द्वारा आवंटित ब्लॉक से परे लिखने का प्रयास करेगा malloc
।
यदि यह क्षेत्र प्रक्रिया के स्वामित्व में नहीं है, तो सेगफॉल्ट को तुरंत ट्रिगर किया जाना चाहिए।
अभी भी अधिक विनाशकारी - और सूक्ष्म --- स्थिति है जब निम्न ब्लॉक उठता है प्रक्रिया के स्वामित्व में है, तो त्रुटि के लिए नहीं कर सकते हैं पता लगाया जा, कोई संकेत उठाया जा सकता है, और इसलिए यह हो सकता है 'दिखाई' अभी भी 'काम' के लिए , हालांकि यह वास्तव में अन्य डेटा, आपके आवंटनकर्ता के प्रबंधन संरचनाओं, या यहां तक कि कोड (कुछ ऑपरेटिंग वातावरणों में) को अधिलेखित करेगा ।
यही कारण है कि पॉइंटर संबंधित बगों को ट्रैक करना इतना कठिन हो सकता है । कल्पना करें कि इन पंक्तियों को गहन रूप से संबंधित कोड की हजारों लाइनों के भीतर गहरे दफन किया गया है, जिसे किसी और ने लिखा है, और आपको निर्देश दिया गया है।
फिर भी , कार्यक्रम को अभी भी संकलित करना चाहिए , क्योंकि यह पूरी तरह से वैध और मानक अनुरूप सीबना हुआ है ।
इस प्रकार की त्रुटियां, कोई मानक और कोई संकलक अनैच्छिक रक्षा नहीं कर सकते हैं। मुझे लगता है कि वास्तव में वे आपको पढ़ाने का इरादा कर रहे हैं।
पैरानॉयड लोग लगातार इन समस्याग्रस्त संभावनाओं के निपटान के लिए सी की प्रकृति को बदलना चाहते हैं और इसलिए हमें खुद से बचाते हैं; लेकिन यह अपमानजनक है । यह वह जिम्मेदारी है जिसे हम स्वीकार करने के लिए बाध्य होते हैं जब हम सत्ता का पीछा करने के लिए चुनते हैं और स्वतंत्रता प्राप्त करते हैं जो मशीन का अधिक प्रत्यक्ष और व्यापक नियंत्रण हमें प्रदान करता है। प्रदर्शन में पूर्णता के प्रवर्तक और अनुयायी कभी भी कुछ कम स्वीकार नहीं करेंगे।
पोर्टेबिलिटी और सामान्यता जो इसका प्रतिनिधित्व करती है, एक मौलिक रूप से अलग विचार है और सभी जो मानक को संबोधित करता है:
यह दस्तावेज़ प्रपत्र को निर्दिष्ट करता है और प्रोग्रामिंग भाषा सी में व्यक्त किए गए कार्यक्रमों की व्याख्या स्थापित करता है। इसका उद्देश्य विभिन्न कंप्यूटिंग प्रणालियों पर सी भाषा कार्यक्रमों के पोर्टेबिलिटी , विश्वसनीयता, रखरखाव और कुशल निष्पादन को बढ़ावा देना है ।
यही कारण है कि इसे भाषा की परिभाषा और तकनीकी विनिर्देश से अलग रखना पूरी तरह से उचित है। कई क्या के विपरीत विश्वास करने लगते हैं व्यापकता है विरोधात्मक को असाधारण और अनुकरणीय ।
समाप्त करने के लिए:
- बिंदुओं की जांच करना और हेरफेर करना हमेशा ही मान्य और अक्सर फलदायी होता है । परिणामों की व्याख्या, अर्थपूर्ण हो सकती है या नहीं भी हो सकती है, लेकिन जब तक कि पॉइंटर को स्थगित नहीं किया जाता है , तब तक विपत्ति को कभी भी आमंत्रित नहीं किया जाता है ; जब तक इससे जुड़े पते तक पहुंचने का प्रयास नहीं किया जाता ।
क्या यह सच नहीं था, प्रोग्रामिंग जैसा कि हम जानते हैं - और इसे प्यार करते हैं - संभव नहीं था।
C
क्या है के साथ सुरक्षित मेंC
। एक ही प्रकार के दो बिंदुओं की तुलना हमेशा की जा सकती है (उदाहरण के लिए समानता की जाँच), हालांकि, सूचक अंकगणितीय और तुलना का उपयोग करना>
और<
केवल तब ही सुरक्षित है जब किसी दिए गए सरणी (या मेमोरी ब्लॉक) के भीतर उपयोग किया जाता है ।