2009-10-14 9 views
19

मुझे सेगमेंटेशन गलती के मूल कारण को जानने की ज़रूरत है, और कोई भी मुझे बता सकता है कि इसे कैसे संभालना है।सी ++ में SIGSEGV रन टाइम त्रुटि क्या है?

+4

@GMan - मूल कारण शायद पॉइंटर्स की एक बेवकूफ समझ है। ओपी के बारे में कुछ भी नहीं कह रहा है - यह उसका कोड नहीं हो सकता है - बस किसी को नहीं पता था कि पॉइंटर्स का सही तरीके से उपयोग कैसे करें। –

+0

पेजिंग के बारे में जानें: http://stackoverflow.com/questions/18431261/how-does-x86-paging-work –

उत्तर

37

Wikipedia कई अन्य स्रोतों के साथ उत्तर है।

एक सेगफॉल्ट मूल रूप से मतलब है कि आपने पॉइंटर्स के साथ कुछ बुरा किया है।

char *c = NULL; 
... 
*c; // dereferencing a NULL pointer 

या इस: यह शायद एक segfault है

char *c = "Hello"; 
... 
c[10] = 'z'; // out of bounds, or in this case, writing into read-only memory 

या हो सकता है यह:

char *c = new char[10]; 
... 
delete [] c; 
... 
c[2] = 'z'; // accessing freed memory 

प्रत्येक मामले में एक ही बुनियादी सिद्धांत - आप स्मृति कि isn के साथ कुछ कर रहे तुम्हारा नहीं

3

अमान्य/शून्य सूचक का उपयोग कर? एक सरणी की सीमाओं को खत्म करना? किसी भी नमूना कोड के बिना विशिष्ट होना मुश्किल है।

अनिवार्य रूप से, आप उस स्मृति तक पहुंचने का प्रयास कर रहे हैं जो आपके प्रोग्राम से संबंधित नहीं है, इसलिए ओएस इसे मार देता है।

4

यहां SIGSEGV का एक उदाहरण है।

[email protected]:/opt/playGround# cat test.c 
int main() 
{ 
    int * p ; 
    * p = 0x1234; 
    return 0 ; 
} 
[email protected]:/opt/playGround# g++ -o test test.c 
[email protected]:/opt/playGround# ./test 
Segmentation fault 

और यहां detail है।

इसे कैसे संभालें?

  1. पहली जगह में संभव के रूप में यह रूप में ज्यादा से बचें।

    रक्षात्मक रूप से प्रोग्राम: assert() का उपयोग करें, नल पॉइंटर के लिए जांचें, बफर ओवरफ़्लो की जांच करें।

    अपने कोड की जांच के लिए स्थिर विश्लेषण उपकरण का उपयोग करें।

    अपने कोड को संकलित करें -Werror -Wall।

    क्या कोई आपके कोड की समीक्षा करता है।

  2. जब वास्तव में ऐसा हुआ।

    आपको कोड सावधानी से जांचें।

    जांचें कि पिछली बार जब आप क्रैश के बिना सफलतापूर्वक कोड चलाते हैं तो आपने क्या बदल दिया है।

    उम्मीद है कि, जीडीबी आपको एक कॉल स्टैक देगा ताकि आपको पता चले कि दुर्घटना कहाँ हुई।


संपादित करें: एक भीड़ के लिए खेद है। यह p = 0x1234 के बजाय *p = 0x1234; होना चाहिए;

+0

पॉइंटर को अमान्य मान क्यों असाइन करना होगा और सूचक SIGSEGV को संदर्भित नहीं करना चाहिए? – sharptooth

+1

यह प्रोग्राम किसी भी C++ संकलक के साथ संकलित नहीं होगा। यदि आप आवश्यक कास्ट जोड़ते हैं, तो यह क्रैश नहीं होगा, क्योंकि इसमें वास्तव में कोई अमान्य स्मृति पहुंच नहीं है। –

+0

सख्ती से बोलते हुए, एक पॉइंटर ऑब्जेक्ट में मनमाने ढंग से मूल्य को मजबूर करने से सी/सी ++ प्रोग्राम किसी भी अपमानजनक प्रयास के बिना तुरंत क्रैश हो सकता है ("जाल प्रस्तुतिकरण" पर पढ़ा जाता है), लेकिन ऐसा कुछ नहीं है जिसमें हममें से अधिकांश को सामना करना पड़ता है अभ्यास। और, ज़ाहिर है, यह SIGSEGV को चित्रित करने के लिए एक अच्छा उदाहरण नहीं है :) – AnT

11

सेगमेंटेशन दोषों के कई कारण हैं, लेकिन मूल रूप से, आप स्मृति को गलत तरीके से एक्सेस कर रहे हैं।यह एक शून्य सूचक को dereferencing, या रीडोनली स्मृति को संशोधित करने की कोशिश कर सकता है, या कहीं भी एक सूचक का उपयोग करके जो आपकी प्रक्रिया की स्मृति स्थान में मैप नहीं किया गया है (शायद इसका मतलब है कि आप एक सूचक के रूप में एक संख्या का उपयोग करने की कोशिश कर रहे हैं , या आपने एक सूचक को बहुत दूर बढ़ाया है)। कुछ मशीनों पर, समस्या का कारण बनने के लिए एक पॉइंटर के माध्यम से गलत तरीके से पहुंच के लिए भी संभव है - यदि आपके पास कोई अजीब पता है और इससे भी बाइट्स को पढ़ने की कोशिश करें, उदाहरण के लिए (जो इसके बजाय सिगबस उत्पन्न कर सकता है)।

+0

यहां विभिन्न त्रुटि संकेत खराब हैं परिभाषित - ओएस एक्स पर, 'char * c = NULL; * सी; 'वास्तव में एक SIGSEGV के बजाय एक सिगब्स उत्पन्न करता है। –

+0

हां - सिगबस और एसआईजीएसईजीवी दोनों कुछ हद तक सिस्टम और/या प्रोसेसर विशिष्ट हैं। दोनों का मतलब है कि आप स्मृति का दुरुपयोग कर रहे हैं। न तो स्वस्थ है। –

संबंधित मुद्दे