C++ में Segmentation Fault: कारण, डिबगिंग और इससे कैसे बचें

शुरुआती लोगों के लिए ऑनलाइन Python प्रशिक्षक

Python आसानी से सीखें बिना सिद्धांत के बोझ के। स्वचालित जांच के साथ व्यावहारिक कार्य हल करें और ब्राउज़र में सीधे कोड लिखें।

पाठ्यक्रम शुरू करें

Segmentation Fault: केवल एक त्रुटि नहीं, बल्कि C++ मेमोरी की दुनिया का द्वार

\n\n

यदि आपने कभी C++ में कोड लिखा है और टर्मिनल में छोटा लेकिन डरावना संदेश Segmentation fault (core dumped) देखा है, तो आप अकेले नहीं हैं। यह सिग्नल शुरुआती (और अनुभवी) डेवलपर्स के सबसे लोकप्रिय दुश्मनों में से एक है। Stack Overflow पर प्रश्न "What is a segmentation fault?" ने सैकड़ों हज़ारों बार देखा गया है। लेकिन इस त्रुटि के पीछे कुछ और भी छिपा है: मेमोरी, पॉइंटर्स और आपके कोड के प्रदर्शन की गहरी समझ।

\n\n

इस लेख में हम केवल यह नहीं समझेंगे कि segfault क्या है। हम इसे खोजना, ठीक करना और सबसे महत्वपूर्ण, इसे रोकना सीखेंगे। और साथ ही यह भी जानेंगे कि यह त्रुटि कोड अनुकूलन से कैसे संबंधित है और इसका दिखना प्रदर्शन समस्याओं का संकेत क्यों हो सकता है।

\n\n

सरल शब्दों में segmentation fault क्या है?

\n\n

Segmentation fault (सेगमेंटेशन त्रुटि) आपके प्रोग्राम को ऑपरेटिंग सिस्टम का एक संकेत है: "आप उस मेमोरी तक पहुँचने का प्रयास कर रहे हैं जो आपकी नहीं है।" कल्पना करें कि आप एक अपार्टमेंट किराए पर लेते हैं (आपकी प्रक्रिया) और अचानक दीवार के माध्यम से पड़ोसी में प्रवेश करने का प्रयास करते हैं। सुरक्षा (OS) आपको रोकती है और इमारत से बाहर निकाल देती है।

\n\n

C++ में यह तब होता है जब प्रोग्राम मेमोरी के गलत पते पर पहुँचता है। उदाहरण के लिए, शून्य पॉइंटर पर, पहले से मुक्त की गई मेमोरी पर, या सरणी की सीमा से बाहर। Java या Python के विपरीत, जहाँ वर्चुअल मशीन मेमोरी सुरक्षा के लिए जिम्मेदार होती है, C++ आपको पूर्ण नियंत्रण देता है। और नियंत्रण के साथ जिम्मेदारी भी आती है।

\n\n

कोड में यह कैसा दिखता है?

\n\n
#include <iostream>\n\nint main() {\n    int* ptr = nullptr;  // शून्य पॉइंटर\n    *ptr = 42;           // segmentation fault!\n    return 0;\n}
\n\n

पहली नज़र में, त्रुटि स्पष्ट है। लेकिन वास्तविक परियोजनाओं में, कारण कहीं अधिक पेचीदा होते हैं। आइए उन्हें क्रम से समझते हैं।

\n\n

C++ में segmentation fault के शीर्ष 5 कारण

\n\n

1. शून्य पॉइंटर को डीरेफरेंस करना

\n

सबसे सामान्य और समझने योग्य कारण। पॉइंटर किसी भी ऑब्जेक्ट की ओर इशारा नहीं करता, और आप उस पते पर डेटा लिखने या पढ़ने का प्रयास करते हैं।

\n\n
int* p = nullptr;\nstd::cout << *p;  // segfault
\n\n

कैसे बचें: उपयोग करने से पहले हमेशा पॉइंटर्स की जाँच करें:

\n\n
if (p != nullptr) {\n    std::cout << *p;\n}
\n\n

2. सरणी की सीमा से बाहर जाना

\n

C++ सरणी इंडेक्स की जाँच नहीं करता। यदि आप arr[100] तक पहुँचते हैं जब सरणी 10 तत्वों के लिए बनाई गई है, तो आप दूसरे की मेमोरी पढ़ या लिख रहे हैं।

\n\n
int arr[10];\narr[15] = 5;  // संभावित segfault
\n\n

यह विशेष रूप से कपटी है क्योंकि त्रुटि तुरंत प्रकट नहीं हो सकती, बल्कि बाद में प्रोग्राम के पूरी तरह से अलग स्थान पर दिखाई दे सकती है। ऐसे बग को डीबग करना बहुत कठिन होता है।

\n\n

3. मुक्त करने के बाद उपयोग (use-after-free)

आपने मेमोरी मुक्त कर दी (delete या free), लेकिन उस पर पॉइंटर का उपयोग जारी रखते हैं। मेमोरी पहले ही किसी अन्य प्रक्रिया को दे दी गई हो सकती है या ओवरराइट कर दी गई हो सकती है।

\n\n
int* ptr = new int(10);\ndelete ptr;\n*ptr = 20;  // segfault — मुक्त करने के बाद उपयोग
\n\n

सुझाव: delete के बाद पॉइंटर को nullptr असाइन करें।

\n\n
delete ptr;\nptr = nullptr;
\n\n

4. स्टैक ओवरफ्लो (stack overflow)

\n

हालाँकि यह क्लासिक segfault नहीं है, स्टैक ओवरफ्लो अक्सर उसी सिग्नल की ओर ले जाता है। यह तब होता है जब आप बहुत अधिक स्थानीय वेरिएबल बनाते हैं या अनंत रिकर्सन में चले जाते हैं।

\n\n
void infinite() {\n    int huge[1000000];  // स्टैक पर बहुत बड़ी सरणी\n    infinite();          // बिना निकास के रिकर्सन\n}
\n\n

5. reinterpret_cast का गलत उपयोग

\n

C++ में टाइप कास्टिंग एक शक्तिशाली लेकिन खतरनाक उपकरण है। यदि आप मेमोरी की गलत व्याख्या करते हैं, तो segfault आने में देर नहीं लगेगी।

ब्लॉग

पुस्तक अनुशंसाएँ