उदाहरण
int *ptr;
*ptr = 1000;
क्या मैं किसी भी Microsoft विशिष्ट का उपयोग किए बिना मानक C ++ का उपयोग करके मेमोरी एक्सेस उल्लंघन अपवाद को पकड़ सकता हूं।
उदाहरण
int *ptr;
*ptr = 1000;
क्या मैं किसी भी Microsoft विशिष्ट का उपयोग किए बिना मानक C ++ का उपयोग करके मेमोरी एक्सेस उल्लंघन अपवाद को पकड़ सकता हूं।
जवाबों:
नहीं। जब आप कुछ बुरा करते हैं, तो C ++ अपवाद नहीं फेंकता है, जिससे प्रदर्शन प्रभावित होगा। भाषा-स्तरीय चीज़ों के बजाय शून्य त्रुटियों द्वारा एक्सेस उल्लंघन या विभाजन जैसे त्रुटि "मशीन" अपवादों की तरह हैं।
इसे पढ़ें और रोएं!
मैं यह समझ गया। यदि आप हैंडलर से नहीं फेंकते हैं, तो हैंडलर बस जारी रहेगा और इसलिए अपवाद होगा।
जादू तब होता है जब आप खुद को अपवाद फेंकते हैं और संभालते हैं।
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <tchar.h>
void SignalHandler(int signal)
{
printf("Signal %d",signal);
throw "!Access Violation!";
}
int main()
{
typedef void (*SignalHandlerPointer)(int);
SignalHandlerPointer previousHandler;
previousHandler = signal(SIGSEGV , SignalHandler);
try{
*(int *) 0 = 0;// Baaaaaaad thing that should never be caught. You should write good code in the first place.
}
catch(char *e)
{
printf("Exception Caught: %s\n",e);
}
printf("Now we continue, unhindered, like the abomination never happened. (I am an EVIL genius)\n");
printf("But please kids, DONT TRY THIS AT HOME ;)\n");
}
sigaltstack
) स्थापित नहीं होना चाहिए (जब तक कि C ++ अपवाद को लागू नहीं करता है), और हर रनिंग फ़ंक्शन को अनइंडिंग सिस्टम को स्वयं सिग्नल-सुरक्षित होना चाहिए।
signal(SIGSEGV, SIG_DFL);
किसी भी प्रकार के अपवाद को पकड़ने का एक बहुत ही आसान तरीका है विजुअल स्टूडियो में प्रयास (> कैच ... (...) ब्लॉक का उपयोग करके। एक मामूली परियोजना सेटिंग्स ट्विकिंग पर्याप्त है। प्रोजेक्ट सेटिंग्स में बस सक्षम / ईएचए विकल्प। प्रोजेक्ट गुण देखें -> C / C ++ -> कोड जेनरेशन -> सक्षम करें C ++ एक्सेप्शन को "हाँ, SEH अपवाद के साथ" संशोधित करें । बस!
यहां देखें विवरण: http://msdn.microsoft.com/en-us/library/1deeycx5(v=vs.80).aspx
कम से कम मेरे लिए, signal(SIGSEGV ...)
एक अन्य उत्तर में वर्णित दृष्टिकोण विजुअल C ++ 2015 के साथ Win32 पर काम नहीं किया । क्या किया था मेरे लिए काम का उपयोग किया गया _set_se_translator()
में पाया eh.h
। यह इस तरह काम करता है:
चरण 1 ) सुनिश्चित करें कि आप प्रोजेक्ट गुणों / सी ++ / कोड जनरेशन / सक्षम सी ++ अपवादों में एसईएच अपवादों (/ ईएचए) के साथ हां को सक्षम करते हैं , जैसा कि वलोडिमिर फ्रायत्स्की द्वारा जवाब में उल्लेख किया गया है ।
चरण 2 ) कॉल _set_se_translator()
, नए अपवाद अनुवादक के लिए एक फ़ंक्शन पॉइंटर (या लैम्ब्डा) में गुजर रहा है । इसे एक अनुवादक कहा जाता है क्योंकि यह मूल रूप से केवल निम्न-स्तरीय अपवाद लेता है और इसे पकड़ने में आसान के रूप में पुन: फेंकता है, जैसे std::exception
:
#include <string>
#include <eh.h>
// Be sure to enable "Yes with SEH Exceptions (/EHa)" in C++ / Code Generation;
_set_se_translator([](unsigned int u, EXCEPTION_POINTERS *pExp) {
std::string error = "SE Exception: ";
switch (u) {
case 0xC0000005:
error += "Access Violation";
break;
default:
char result[11];
sprintf_s(result, 11, "0x%08X", u);
error += result;
};
throw std::exception(error.c_str());
});
चरण 3 ) सामान्य रूप से आप जैसे अपवाद को पकड़ेंगे:
try{
MakeAnException();
}
catch(std::exception ex){
HandleIt();
};
इस प्रकार की स्थिति कार्यान्वयन पर निर्भर है और फलस्वरूप इसे फँसाने के लिए एक विक्रेता विशिष्ट तंत्र की आवश्यकता होगी। Microsoft के साथ इसमें SEH शामिल होगा, और * nix में एक सिग्नल शामिल होगा
सामान्य तौर पर हालांकि एक एक्सेस उल्लंघन अपवाद को पकड़ना एक बहुत बुरा विचार है। एवी अपवाद से उबरने का लगभग कोई रास्ता नहीं है और ऐसा करने का प्रयास करने से आपके कार्यक्रम में बग ढूंढना मुश्किल हो जाएगा।
जैसा कि कहा गया है, विंडोज़ प्लेटफॉर्म पर ऐसा करने के लिए कोई गैर-माइक्रोसॉफ्ट / कंपाइलर विक्रेता तरीका नहीं है। हालाँकि, इस प्रकार के अपवादों को सामान्य प्रयास में पकड़ने के लिए स्पष्ट रूप से उपयोगी है {} कैच (अपवाद पूर्व) {} रास्ते में त्रुटि रिपोर्टिंग के लिए और आपके ऐप के अधिक सुंदर निकास के रूप में (जैसा कि JaredPar कहता है, ऐप अब मुश्किल में है) । हम एक साधारण श्रेणी के रैपर में _se_translator_function का उपयोग करते हैं, जो हमें एए हैंडलर में निम्नलिखित अपवादों को पकड़ने की अनुमति देता है:
DECLARE_EXCEPTION_CLASS(datatype_misalignment)
DECLARE_EXCEPTION_CLASS(breakpoint)
DECLARE_EXCEPTION_CLASS(single_step)
DECLARE_EXCEPTION_CLASS(array_bounds_exceeded)
DECLARE_EXCEPTION_CLASS(flt_denormal_operand)
DECLARE_EXCEPTION_CLASS(flt_divide_by_zero)
DECLARE_EXCEPTION_CLASS(flt_inexact_result)
DECLARE_EXCEPTION_CLASS(flt_invalid_operation)
DECLARE_EXCEPTION_CLASS(flt_overflow)
DECLARE_EXCEPTION_CLASS(flt_stack_check)
DECLARE_EXCEPTION_CLASS(flt_underflow)
DECLARE_EXCEPTION_CLASS(int_divide_by_zero)
DECLARE_EXCEPTION_CLASS(int_overflow)
DECLARE_EXCEPTION_CLASS(priv_instruction)
DECLARE_EXCEPTION_CLASS(in_page_error)
DECLARE_EXCEPTION_CLASS(illegal_instruction)
DECLARE_EXCEPTION_CLASS(noncontinuable_exception)
DECLARE_EXCEPTION_CLASS(stack_overflow)
DECLARE_EXCEPTION_CLASS(invalid_disposition)
DECLARE_EXCEPTION_CLASS(guard_page)
DECLARE_EXCEPTION_CLASS(invalid_handle)
DECLARE_EXCEPTION_CLASS(microsoft_cpp)
मूल वर्ग इस बहुत उपयोगी लेख से आया है:
अपवाद हैंडलिंग तंत्र नहीं है, लेकिन आप सिग्नल () तंत्र का उपयोग कर सकते हैं जो सी द्वारा प्रदान किया गया है।
> man signal
11 SIGSEGV create core image segmentation violation
NULL पॉइंटर पर लिखना संभवतः SIGSEGV सिग्नल का कारण बनता है
signal()
मानक का हिस्सा है। विंडोज पॉज़िक्स मानक को लागू करता है (जैसा कि लिनक्स और यूनिक्स करता है)
इस तरह उल्लंघन का मतलब है कि कोड के साथ कुछ गंभीर रूप से गलत है, और यह अविश्वसनीय है। मैं देख सकता हूं कि एक प्रोग्राम उपयोगकर्ता के डेटा को इस तरह से सहेजने की कोशिश कर सकता है कि कोई आशा पिछले डेटा पर नहीं लिखेगा, इस उम्मीद में कि उपयोगकर्ता का डेटा पहले से भ्रष्ट नहीं है, लेकिन परिभाषा के अनुसार कोई मानक विधि नहीं है अपरिभाषित व्यवहार से निपटना।