त्रुटिविभाजन दोष (कोर डंप) C या C++ में इसका मतलब है कि आपके प्रोग्राम ने मेमोरी तक पहुंचने का प्रयास किया है, उसे इसकी अनुमति नहीं है। यह सबसे आम और निराशाजनक C/C++ त्रुटियों में से एक है। यहां प्रत्येक सामान्य कारण का निदान और समाधान करने का तरीका बताया गया है।
📋 Table of Contents
- वास्तव में सेगफॉल्ट क्या है
- कारण 1: एक शून्य सूचक को असंदर्भित करना
- कारण 2: बफ़र ओवरफ़्लो (सीमा से बाहर पहुंच)
- कारण 3: उपयोग के बाद-मुक्त (लटकने वाला सूचक)
- कारण 4: स्टैक ओवरफ्लो (अनंत रिकर्सन)
- जीडीबी के साथ डिबगिंग
- वालग्रिंड के साथ मेमोरी बग ढूँढना
- एड्रेस सेनिटाइज़र का उपयोग करना (तेज़, बिल्ट-इन)
- अक्सर पूछे जाने वाले प्रश्न
- निष्कर्ष
वास्तव में सेगफॉल्ट क्या है
सेगमेंटेशन दोष तब होता है जब आपका प्रोग्राम ओएस द्वारा दी गई मेमोरी से बाहर मेमोरी तक पहुंचता है – एक अमान्य पॉइंटर को डीरेफ़र करना, किसी एरे की सीमा से आगे लिखना, या मुक्त मेमोरी का उपयोग करना। ओएस सिस्टम की सुरक्षा के लिए प्रोग्राम को बंद कर देता है और उसकी स्थिति (“कोर डंप”) को डंप कर देता है।
कारण 1: एक शून्य सूचक को असंदर्भित करना
// 🐛 Accessing a NULL or uninitialized pointer
int *ptr = NULL;
*ptr = 42; // ❌ segfault — writing to address 0
int *uninitialized; // points to garbage
*uninitialized = 5; // ❌ segfault (undefined behavior)
// ✅ Always initialize and check pointers
int value = 42;
int *ptr = &value
if (ptr != NULL) {
*ptr = 10; // safe
}
कारण 2: बफ़र ओवरफ़्लो (सीमा से बाहर पहुंच)
// 🐛 Writing past the end of an array
int arr[5];
for (int i = 0; i <= 5; i++) { // ❌ i=5 is out of bounds
arr[i] = i; // arr[5] doesn't exist
}
// ✅ Correct bounds
for (int i = 0; i < 5; i++) { // i < 5, not <=
arr[i] = i;
}
// 🐛 strcpy overflow
char dest[5];
strcpy(dest, "This is too long"); // ❌ overflows dest
// ✅ Use bounded copy
char dest[20];
strncpy(dest, "safe copy", sizeof(dest) - 1);
dest[sizeof(dest) - 1] = '\0';
कारण 3: उपयोग के बाद-मुक्त (लटकने वाला सूचक)
// 🐛 Using memory after freeing it
int *ptr = malloc(sizeof(int));
*ptr = 42;
free(ptr);
*ptr = 10; // ❌ segfault — ptr is dangling
// ✅ Set to NULL after freeing
free(ptr);
ptr = NULL; // prevents accidental reuse
// if (ptr) *ptr = 10; // now safely skipped
कारण 4: स्टैक ओवरफ्लो (अनंत रिकर्सन)
// 🐛 Recursion with no base case exhausts the stack
int factorial(int n) {
return n * factorial(n - 1); // ❌ never stops → stack overflow
}
// ✅ Add a base case
int factorial(int n) {
if (n <= 1) return 1; // base case
return n * factorial(n - 1);
}
// 🐛 Huge local array can also overflow the stack
void func() {
int huge[10000000]; // ❌ too big for the stack
}
// ✅ Allocate large data on the heap
void func() {
int *huge = malloc(10000000 * sizeof(int));
// ... use it ...
free(huge);
}
जीडीबी के साथ डिबगिंग
# Compile with debug symbols
gcc -g -o myprogram myprogram.c
# Run under gdb
gdb ./myprogram
(gdb) run
# When it crashes:
Program received signal SIGSEGV, Segmentation fault.
0x0000... in main () at myprogram.c:15
# See the exact line and call stack
(gdb) backtrace # shows the call stack
(gdb) print ptr # inspect the bad pointer
(gdb) frame 1 # move up the stack
(gdb) list # show surrounding code
वालग्रिंड के साथ मेमोरी बग ढूँढना
# Valgrind catches invalid access, leaks, and use-after-free
valgrind --leak-check=full ./myprogram
# Output pinpoints the problem:
# Invalid write of size 4
# at 0x... in main (myprogram.c:15)
# Address 0x0 is not stack'd, malloc'd or (recently) free'd
# It shows exactly where and what kind of memory error occurred
एड्रेस सेनिटाइज़र का उपयोग करना (तेज़, बिल्ट-इन)
# Compile with AddressSanitizer — catches many bugs at runtime
gcc -fsanitize=address -g -o myprogram myprogram.c
./myprogram
# ASan reports:
# ERROR: AddressSanitizer: heap-buffer-overflow
# WRITE of size 4 at 0x...
# #0 in main myprogram.c:15
# Much faster than Valgrind and often clearer output
अक्सर पूछे जाने वाले प्रश्न
प्रश्न: “कोर डंप्ड” का क्या मतलब है?
उ: जब प्रोग्राम क्रैश हो जाता है, तो ओएस एक “कोर डंप” लिखता है – क्रैश होने पर प्रोग्राम की मेमोरी का एक स्नैपशॉट। दुर्घटना के समय स्थिति का निरीक्षण करने के लिए आप इसे gdb (gdb ./program core) में लोड कर सकते हैं।
प्रश्न: मेरा प्रोग्राम कभी-कभी क्रैश क्यों हो जाता है, हमेशा नहीं?
उ: अपरिभाषित व्यवहार (जैसे कि अप्रारंभीकृत मेमोरी या मामूली बफर ओवरफ़्लो का उपयोग करना) हमेशा एक दृश्यमान क्रैश को ट्रिगर नहीं कर सकता है – यह इस पर निर्भर करता है कि मेमोरी में क्या होता है। यह ऐसे बग को खतरनाक बनाता है; उन्हें विश्वसनीय रूप से पकड़ने के लिए ASan/Valgrind का उपयोग करें।
प्रश्न: जीडीबी बनाम वालग्रिंड बनाम एड्रेस सैनिटाइज़र – मुझे किसका उपयोग करना चाहिए?
उत्तर: एड्रेस सेनिटाइजर (संकलन ध्वज) सबसे तेज है और अधिकांश मेमोरी बग को पकड़ता है – यहां से शुरू करें। वेलग्रिंड लीक के लिए पूरी तरह से उपयुक्त है और इसे पुन:संकलन की आवश्यकता नहीं है। जीडीबी किसी विशिष्ट दुर्घटना का अंतःक्रियात्मक रूप से निरीक्षण करने के लिए है। अक्सर आप गहराई तक जाने के लिए पहले ASan का उपयोग करते हैं, फिर gdb का।
प्रश्न: मैं सबसे पहले सेगफ़ॉल्ट्स को कैसे रोकूँ?
ए: पॉइंटर्स को इनिशियलाइज़ करें, डीरेफ़रेंसिंग से पहले NULL की जाँच करें, ऐरे की सीमाओं का सम्मान करें, फ़्री होने के बाद पॉइंटर्स को NULL पर सेट करें, और आधुनिक C++ स्मार्ट पॉइंटर्स (unique_ptr, shared_ptr) का उपयोग करें जो मेमोरी को स्वचालित रूप से प्रबंधित करते हैं।
प्रश्न: क्या मुझे आधुनिक C++ में रॉ पॉइंटर्स का उपयोग करना चाहिए?
ए: स्मार्ट पॉइंटर्स और कंटेनर (वेक्टर, स्ट्रिंग) को प्राथमिकता दें जो मेमोरी को सुरक्षित रूप से संभालते हैं और अधिकांश सेगफॉल्ट कारणों को खत्म करते हैं। कच्चे पॉइंटर्स अभी भी गैर-स्वामित्व वाले संदर्भों के लिए उपयोगी हैं, लेकिन जहां RAII प्रकार काम करते हैं वहां मैन्युअल रूप से नए/हटाने से बचें।
निष्कर्ष
सेगमेंटेशन दोष का अर्थ है अमान्य मेमोरी एक्सेस – आमतौर पर एक NULL/लटकने वाला पॉइंटर, बफर ओवरफ़्लो, या स्टैक ओवरफ़्लो। डिबगिंग वर्कफ़्लो: के साथ संकलित करें , इसे चलाएं (एड्रेससेनिटाइज़र सटीक लाइन और बग प्रकार को इंगित करता है), या जीडीबी का उपयोग करें-fsanitize=address -g दुर्घटना स्थान देखने के लिएbacktrace. उन्हें रोकने के लिए: पॉइंटर्स को इनिशियलाइज़ करें, NULL की जाँच करें, सीमाओं का सम्मान करें, NULL-आउट फ़्रीड पॉइंटर्स, और C++ में स्मार्ट पॉइंटर्स और कंटेनर्स का उपयोग करें। एएसएएन जैसे आधुनिक उपकरण एक बार रहस्यमय सेगफॉल्ट को तुरंत ढूंढने और ठीक करने में सक्षम बनाते हैं।. उन्हें रोकने के लिए: पॉइंटर्स को इनिशियलाइज़ करें, NULL की जाँच करें, सीमाओं का सम्मान करें, NULL-आउट फ़्रीड पॉइंटर्स, और C++ में स्मार्ट पॉइंटर्स और कंटेनर्स का उपयोग करें। एएसएएन जैसे आधुनिक उपकरण एक बार रहस्यमय सेगफॉल्ट को तुरंत ढूंढने और ठीक करने में सक्षम बनाते हैं।
🔗 Share this article
✍️ Leave a Comment