एक विभाजन दोष क्या है? क्या यह C और C ++ में भिन्न है? विभाजन दोष और लटकने वाले बिंदु कैसे संबंधित हैं?
NullPointerException
।
एक विभाजन दोष क्या है? क्या यह C और C ++ में भिन्न है? विभाजन दोष और लटकने वाले बिंदु कैसे संबंधित हैं?
NullPointerException
।
जवाबों:
सेगमेंटेशन दोष एक विशिष्ट प्रकार की त्रुटि है जो मेमोरी तक पहुंचने के कारण होती है जो "आपके पास नहीं है।" यह एक सहायक तंत्र है जो आपको मेमोरी को दूषित करने और हार्ड-टू-डिबग मेमोरी बग्स को पेश करने से रोकता है। जब भी आपको एक सेगफॉल्ट मिलता है, तो आप जानते हैं कि आप मेमोरी के साथ कुछ गलत कर रहे हैं - ऐसे वेरिएबल को एक्सेस करना जो पहले ही मुक्त हो चुका है, मेमोरी के केवल-पढ़ने वाले हिस्से को लिखना, आदि सेग्मेंटेशन दोष अनिवार्य रूप से अधिकांश भाषाओं में समान है जो आपको गड़बड़ करते हैं। स्मृति प्रबंधन, सी और सी ++ में segfaults के बीच कोई मुख्य अंतर नहीं है।
सीगफॉल्ट प्राप्त करने के कई तरीके हैं, कम से कम निचले स्तर की भाषाओं जैसे सी (++) में। एक segfault पाने के लिए एक सामान्य तरीका एक अशक्त सूचक है:
int *p = NULL;
*p = 1;
एक अन्य सेगफॉल्ट तब होता है जब आप मेमोरी के एक हिस्से को लिखने की कोशिश करते हैं जिसे केवल-पढ़ने के लिए चिह्नित किया गया था:
char *str = "Foo"; // Compiler marks the constant string as read-only
*str = 'b'; // Which means this is illegal and results in a segfault
डैंग्लिंग पॉइंटर एक ऐसी चीज़ की ओर इशारा करता है जो किसी भी तरह से मौजूद नहीं है, जैसे यहाँ:
char *p = NULL;
{
char c;
p = &c;
}
// Now p is dangling
पॉइंटर p
खतरे में है क्योंकि यह वर्ण चर को इंगित करता है c
जो ब्लॉक समाप्त होने के बाद अस्तित्व में नहीं रहता है। और जब आप संकेतक (जैसे *p='A'
) को झूलने की कोशिश करते हैं , तो आपको शायद एक segfault मिलेगा।
c
यह स्थानीय है, इसका मतलब है कि इसे स्टैक पर धकेल दिया गया है {
और इसके बाद पॉप-एड किया गया है }
। डैंगलिंग पॉइंटर केवल एक ऑफसेट का संदर्भ है जो अब स्टैक से बाहर है। यही कारण है कि एक साधारण कार्यक्रम में इसे संशोधित करना कभी भी किसी सेगफॉल्ट को ट्रिगर नहीं करेगा। दूसरी ओर यह अधिक जटिल उपयोग के मामले में सेगफॉल्ट का कारण बन सकता है, जहां अन्य फ़ंक्शन कॉल स्टैक को बढ़ने और झूलने वाले सूचक द्वारा इंगित किए गए डेटा को शामिल कर सकते हैं। उस डेटा (स्थानीय संस्करण) पर लिखना अपरिभाषित व्यवहार को बढ़ावा देगा (
SIGSEGV
, इसलिए मुझे स्टैक के साथ छेड़छाड़ से ऐसे संकेत की उम्मीद नहीं होगी।
यह ध्यान देने योग्य होगा कि विभाजन की गलती सीधे किसी अन्य प्रक्रिया मेमोरी तक पहुंचने के कारण नहीं होती है (यह वही है जो मैं कभी-कभी सुन रहा हूं), क्योंकि यह बस संभव नहीं है। वर्चुअल मेमोरी के साथ हर प्रक्रिया का अपना वर्चुअल एड्रेस स्पेस होता है और पॉइंटर के किसी भी मूल्य का उपयोग करके किसी दूसरे तक पहुंचने का कोई तरीका नहीं होता है। इसके अपवाद को साझा किया जा सकता है पुस्तकालयों जो एक ही भौतिक पता स्थान के लिए मैप किए गए हैं (संभवतः) अलग-अलग आभासी पते और कर्नेल मेमोरी जो हर प्रक्रिया में उसी तरह से मैप की जाती है (एसआईएससीएल पर टीएलबी फ्लशिंग से बचने के लिए, मुझे लगता है)। और शमाट जैसी चीजें;) - ये वो हैं जिन्हें मैं 'इनडायरेक्ट' एक्सेस के रूप में गिनता हूं। हालाँकि, कोई भी जाँच कर सकता है कि वे आमतौर पर प्रक्रिया कोड से लंबे रास्ते में स्थित हैं और हम आमतौर पर उन्हें एक्सेस करने में सक्षम हैं (यही कारण है कि वे वहां हैं)
फिर भी, हमारी खुद की (प्रक्रिया) मेमोरी को अनुचित तरीके से एक्सेस करने (उदाहरण के लिए गैर-लेखन योग्य स्थान पर लिखने की कोशिश) के मामले में विभाजन की गलती हो सकती है। लेकिन इसका सबसे आम कारण वर्चुअल एड्रेस स्पेस के उस हिस्से तक पहुंच है जो भौतिक रूप से एक मैप नहीं किया जाता है।
और यह सब वर्चुअल मेमोरी सिस्टम के संबंध में है।
एक विभाजन दोष एक पृष्ठ के लिए एक अनुरोध के कारण होता है जिसे प्रक्रिया ने अपने विवरण तालिका में सूचीबद्ध नहीं किया है, या उस पृष्ठ के लिए एक अमान्य अनुरोध जो इसे सूचीबद्ध किया है (उदाहरण के लिए केवल-पढ़ने के लिए एक लेखन अनुरोध)।
डैंगलिंग पॉइंटर एक ऐसा पॉइंटर होता है जो किसी वैध पेज की ओर इशारा करता है या नहीं कर सकता है, लेकिन यह मेमोरी के "अनपेक्षित" सेगमेंट को इंगित करता है।
ईमानदार होने के लिए, जैसा कि अन्य पोस्टरों ने उल्लेख किया है, विकिपीडिया पर इस पर बहुत अच्छा लेख है इसलिए वहां एक नज़र डालें। इस तरह की त्रुटि बहुत आम है और अक्सर अन्य चीजें जैसे एक्सेस वॉयलेशन या सामान्य सुरक्षा दोष।
वे C, C ++ या किसी अन्य भाषा में भिन्न नहीं हैं जो संकेत देता है। इस प्रकार की त्रुटियां आमतौर पर पॉइंटर्स के कारण होती हैं
विकिपीडिया के अनुसार:
एक विभाजन दोष तब होता है जब कोई प्रोग्राम मेमोरी स्थान तक पहुंचने का प्रयास करता है जिसे उसे एक्सेस करने की अनुमति नहीं होती है, या मेमोरी स्थान तक पहुंचने का प्रयास इस तरह से किया जाता है कि अनुमति नहीं है (उदाहरण के लिए, केवल-पढ़ने के लिए लिखने का प्रयास करने के लिए, या ऑपरेटिंग सिस्टम का हिस्सा अधिलेखित करने के लिए)।
सेग्मेंटेशन फॉल्ट भी हार्डवेयर विफलताओं के कारण होता है, इस मामले में रैम की यादें। यह कम सामान्य कारण है, लेकिन अगर आपको अपने कोड में कोई त्रुटि नहीं मिलती है, तो शायद एक यादगार मदद कर सकता है।
इस मामले में समाधान, रैम को बदलें।
संपादित करें:
यहाँ एक संदर्भ है: हार्डवेयर द्वारा विभाजन दोष
सेगमेंटेशन दोष तब होता है जब कोई प्रक्रिया (किसी प्रोग्राम का रनिंग इंस्टेंस) रीड-ओनली मेमोरी एड्रेस या मेमोरी रेंज तक पहुंचने की कोशिश कर रही होती है, जो अन्य प्रक्रिया द्वारा उपयोग की जा रही होती है या नॉन-एज़ेंट (अमान्य) मेमोरी एड्रेस को एक्सेस करती है। डैंगलिंग रेफरेंस (पॉइंटर) समस्या का मतलब है कि किसी ऐसी वस्तु या चर को एक्सेस करने की कोशिश करना, जिसकी सामग्री को पहले ही मेमोरी से हटा दिया गया हो, जैसे:
int *arr = new int[20];
delete arr;
cout<<arr[1]; //dangling problem occurs here
विकिपीडिया के सेगमेंटेशन_फॉल्ट पेज में इसके बारे में बहुत अच्छा वर्णन है, बस इसके कारणों और कारणों की ओर संकेत किया गया है। विस्तृत विवरण के लिए विकी पर एक नज़र डालें।
कंप्यूटिंग में, एक विभाजन दोष (जिसे अक्सर segfault के लिए छोटा किया जाता है) या एक्सेस उल्लंघन एक मेमोरी एक्सेस उल्लंघन के बारे में ऑपरेटिंग सिस्टम (OS) को सूचित करते हुए, मेमोरी प्रोटेक्शन के साथ हार्डवेयर द्वारा उठाया गया एक दोष है।
एक विभाजन दोष के कुछ विशिष्ट कारण निम्नलिखित हैं:
बदले में ये अक्सर उन प्रोग्रामिंग त्रुटियों के कारण होते हैं जिनके परिणामस्वरूप अमान्य मेमोरी एक्सेस होती है:
एक अनइंस्टाल्यूटेड पॉइंटर (वाइल्ड पॉइंटर, जो एक रैंडम मेमोरी एड्रेस की ओर इशारा करता है) को डीफ्रेंसिंग या असाइन करना
मुक्त किए गए पॉइंटर (झूलने वाला पॉइंटर) को डीफ्रेंसिंग या असाइन करना, जो उस मेमोरी को इंगित करता है जिसे फ्रीज / डिलीट / डिलीट किया गया है)
एक बफर अतिप्रवाह।
एक ढेर अतिप्रवाह।
एक प्रोग्राम को निष्पादित करने का प्रयास करना जो सही ढंग से संकलित नहीं करता है। (कुछ संकलक संकलन-समय त्रुटियों की उपस्थिति के बावजूद एक निष्पादन योग्य फ़ाइल का उत्पादन करेंगे।)
सरल शब्दों में: सेगमेंटेशन फॉल्ट ऑपरेटिंग सिस्टम को प्रोग्राम को एक संकेत भेजते हुए कहता है कि उसने एक अवैध मेमोरी एक्सेस का पता लगाया है और मेमोरी को दूषित होने से बचाने के लिए प्रोग्राम को समय से पहले समाप्त कर रहा है।
"सेगमेंटेशन फ़ॉल्ट" का अर्थ है कि आपने उस मेमोरी को एक्सेस करने की कोशिश की है जिसकी आपके पास पहुँच नहीं है।
पहली समस्या मुख्य के आपके तर्कों के साथ है। मुख्य कार्य होना चाहिए int main(int argc, char *argv[])
, और आपको यह देखना चाहिए कि argv तक पहुँचने से पहले argc कम से कम 2 है।
इसके अलावा, जब से आप एक फ्लोट में प्रिंटफ में जा रहे हैं (जो, वैसे, प्रिंटफ से गुजरते समय एक डबल में परिवर्तित हो जाता है), तो आपको% f प्रारूप विनिर्देशक का उपयोग करना चाहिए। % S प्रारूप विनिर्देशक तार के लिए है ('\ 0'-समाप्त वर्ण सरणियाँ)।
एक विभाजन दोष या पहुंच उल्लंघन तब होता है जब कोई प्रोग्राम स्मृति स्थान तक पहुंचने का प्रयास करता है जो मौजूद नहीं है, या किसी स्मृति स्थान तक पहुंचने की कोशिश नहीं करता है, जिसकी अनुमति नहीं है।
/* "Array out of bounds" error
valid indices for array foo
are 0, 1, ... 999 */
int foo[1000];
for (int i = 0; i <= 1000 ; i++)
foo[i] = i;
यहां मैं [1000] मौजूद नहीं है, इसलिए सेगफॉल्ट होता है।
विभाजन दोष के कारण:
it arise primarily due to errors in use of pointers for virtual memory addressing, particularly illegal access.
De-referencing NULL pointers – this is special-cased by memory management hardware.
Attempting to access a nonexistent memory address (outside process’s address space).
Attempting to access memory the program does not have rights to (such as kernel structures in process context).
Attempting to write read-only memory (such as code segment).
"विभाजन गलती" जवाब में के कई अच्छा स्पष्टीकरण हैं, लेकिन विभाजन गलती के साथ के बाद से अक्सर वहाँ स्मृति सामग्री की एक डंप है, मैं जहां के बीच के रिश्ते भाग में "कोर फेंक दिया" साझा करना चाहते थे विभाजन गलती (कोर फेंक दिया) और स्मृति से आता है:
लगभग 1955 से 1975 तक - सेमीकंडक्टर मेमोरी से पहले - कंप्यूटर मेमोरी में प्रमुख प्रौद्योगिकी तांबे के तारों पर टंगे छोटे चुंबकीय डोनट्स का उपयोग करती थी। डोनट्स को "फेराइट कोर" और मुख्य मेमोरी के रूप में जाना जाता था, जिसे "कोर मेमोरी" या "कोर" के रूप में जाना जाता था।
यहां से ले गए ।
विभाजन की गलती की पर्याप्त परिभाषाएं हैं, मैं कुछ उदाहरणों को उद्धृत करना चाहूंगा, जो मुझे प्रोग्रामिंग करते समय आए थे, जो मूर्खतापूर्ण गलतियां लग सकती हैं, लेकिन बहुत समय बर्बाद करेगी।
आप प्रिंटफ़ में argumet प्रकार के बेमेल होने पर नीचे के मामले में विभाजन की गलती पा सकते हैं
#include<stdio.h>
int main(){
int a = 5;
printf("%s",a);
return 0;
}
आउटपुट: Segmentation Fault (SIGSEGV)
जब आप एक पॉइंटर को मेमोरी आवंटित करना भूल जाते हैं, लेकिन इसका उपयोग करने की कोशिश कर रहे हैं।
#include<stdio.h>
typedef struct{
int a;
}myStruct;
int main(){
myStruct *s;
/* few lines of code */
s->a = 5;
return 0;
}
आउटपुट: Segmentation Fault (SIGSEGV)
Segmentation fault
इसका सीधा सा अर्थ यह है कि आप कुछ ऐसी स्मृति तक पहुँचने की कोशिश कर रहे हैं, जो आपकी नहीं है। Segmentation fault
तब होता है जब हम पढ़ने और / या पढ़ने के कार्यों को केवल मेमोरी लोकेशन में लिखने का प्रयास करते हैं या मुक्त मेमोरी की कोशिश करते हैं। दूसरे शब्दों में, हम इसे किसी प्रकार के स्मृति भ्रष्टाचार के रूप में समझा सकते हैं।
नीचे मैं प्रोग्रामर द्वारा की जाने वाली सामान्य गलतियों का उल्लेख करता हूं जो आगे बढ़ती हैं Segmentation fault
।
scanf()
गलत तरीके से उपयोग करना (डाल देना भूल गया &
)।int num;
scanf("%d", num);// must use &num instead of num
int *num;
printf("%d",*num); //*num should be correct as num only
//Unless You can use *num but you have to point this pointer to valid memory address before accessing it.
char *str;
//Stored in read only part of data segment
str = "GfG";
//Problem: trying to modify read only memory
*(str+1) = 'n';
// allocating memory to num
int* num = malloc(8);
*num = 100;
// de-allocated the space allocated to num
free(num);
// num is already freed there for it cause segmentation fault
*num = 110;
printf()
और scanf()
'