উদাহরণ
int *ptr;
*ptr = 1000;
আমি কোনও মাইক্রোসফ্ট নির্দিষ্ট না ব্যবহার করে স্ট্যান্ডার্ড সি ++ ব্যবহার করে মেমরি অ্যাক্সেস লঙ্ঘনের ব্যতিক্রমটি ধরতে পারি?
উত্তর:
নাহ। আপনি যখন খারাপ কিছু করেন তখন সি ++ ব্যতিক্রম হয় না, এতে পারফরম্যান্স হিট হয় hit অ্যাক্সেস লঙ্ঘন বা শূন্য ত্রুটি দ্বারা বিভাজনের মতো জিনিসগুলি আপনি যে ভাষা-স্তরের জিনিসগুলি ধরতে পারেন তার চেয়ে "মেশিন" ব্যতিক্রমের মতো।
এটি পড়ুন এবং কাঁদুন!
আমি এটি বের করেছিলাম। আপনি যদি হ্যান্ডলারের কাছ থেকে না ফেলে থাকেন তবে হ্যান্ডলারটি কেবল চালিয়ে যাবে এবং ব্যতিক্রমও তাই হবে।
যাদুটি ঘটে যখন আপনি নিজের ব্যতিক্রম ছুঁড়ে ফেলেন এবং এটি পরিচালনা করেন।
#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
) ইনস্টল করা উচিত নয় ( সি ++ ব্যতিক্রম আন-বাইন্ডিং বাস্তবায়ন এটির অনুমতি না দিলে) এবং অযৌক্তিক পদ্ধতিতে পরিচালিত প্রতিটি রানটাইম ফাংশন নিজেই সিগন্যাল-নিরাপদ হওয়া উচিত।
signal(SIGSEGV, SIG_DFL);
-> ক্যাচ (...) ব্লক ব্যবহার করে ভিজ্যুয়াল স্টুডিওতে যে কোনও ধরণের ব্যতিক্রম (শূন্য দ্বারা বিভাগ, অ্যাক্সেস লঙ্ঘন ইত্যাদি) ধরার খুব সহজ উপায় রয়েছে । একটি ছোটখাটো প্রকল্প সেটিংস টুইট করা যথেষ্ট। প্রকল্পের সেটিংসে কেবল / EHa বিকল্প সক্ষম করুন। প্রকল্পের বৈশিষ্ট্যগুলি দেখুন -> সি / সি ++ -> কোড জেনারেশন -> "এসইএইচ ব্যতিক্রম সহ হ্যাঁ" এর জন্য সক্ষম সি ++ ব্যতিক্রমগুলি সংশোধন করুন । এটাই!
বিশদটি এখানে দেখুন: http://msdn.microsoft.com/en-us/library/1deeycx5(v=vs.80).aspx
কমপক্ষে আমার পক্ষে, signal(SIGSEGV ...)
অন্য উত্তরে উল্লিখিত পদ্ধতিটি ভিজ্যুয়াল সি ++ 2015 এর সাথে উইন 32 এ কার্যকর হয়নি । আমার জন্য কী কাজ করেছিল তা ব্যবহারে _set_se_translator()
পাওয়া eh.h
। এটি এর মতো কাজ করে:
ধাপ 1 ) নিশ্চিত করুন যে আপনি সক্ষম করুন Seh ব্যতিক্রমসমূহ (/ Eha) সঙ্গে হ্যাঁ মধ্যে প্রকল্প বিষয়বস্তু / সি ++ / কোড নির্মাণ / সি ++ ব্যতিক্রমসমূহ সক্ষম করুন যেমন দ্বারা উত্তর উল্লেখ করা হয়েছে, Volodymyr Frytskyy ।
পদক্ষেপ 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();
};
এই ধরণের পরিস্থিতি বাস্তবায়ন নির্ভর এবং ফলস্বরূপ ফাঁদে যাওয়ার জন্য এটি কোনও বিক্রেতার নির্দিষ্ট পদ্ধতি প্রয়োজন। মাইক্রোসফ্টের সাথে এতে এসইএইচ জড়িত, এবং * নিক্স একটি সংকেত জড়িত
সাধারণভাবে অ্যাক্সেস লঙ্ঘন ব্যতিক্রম ধরা খুব খারাপ ধারণা। কোনও এভি ব্যতিক্রম থেকে পুনরুদ্ধার করার প্রায় কোনও উপায় নেই এবং এটি করার চেষ্টা করা আপনার প্রোগ্রামে বাগগুলি খুঁজে পেতে কেবল আরও শক্তিশালী হতে পারে।
যেমনটি বলা হয়েছে, উইন্ডোজ প্ল্যাটফর্মে এটি করার মতো কোনও অ মাইক্রোসফ্ট / সংকলক বিক্রেতার উপায় নেই। যাইহোক, ত্রুটি প্রতিবেদন করার উপায় এবং আপনার অ্যাপ্লিকেশনটির আরও মনোমুগ্ধকর প্রস্থান (সাধারণভাবে জেয়ার্ডপার বলেছে, অ্যাপটি সম্ভবত সমস্যায় পড়েছে) এই ধরণের ব্যতিক্রমগুলি সাধারণ চেষ্টা in} ধরা (ব্যতিক্রম প্রাক্তন) in উপায়গুলিতে ধরা স্পষ্টভাবে কার্যকর) । আমরা একটি সাধারণ শ্রেণীর মোড়কে _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
কোনও নুল পয়েন্টারটিতে লেখা সম্ভবত একটি SIGSEGV সংকেতের কারণ হতে পারে
signal()
স্ট্যান্ডার্ডের একটি অংশ। উইন্ডোজ পোস্টিক্স স্ট্যান্ডার্ডটি প্রয়োগ করে (লিনাক্স এবং ইউনিক্সের মতো)
এর মতো লঙ্ঘনের অর্থ কোডটির সাথে মারাত্মক কিছু ভুল রয়েছে এবং এটি বিশ্বাসযোগ্য নয়। আমি দেখতে পাচ্ছি যে কোনও প্রোগ্রাম ব্যবহারকারীর ডেটা এমনভাবে সংরক্ষণ করার চেষ্টা করতে পারে যাতে একজন আশা করে যে পূর্ববর্তী ডেটাগুলি এর উপরে লিখবে না, এই আশায় যে ব্যবহারকারীর ডেটা ইতিমধ্যে দূষিত হয়নি, তবে সংজ্ঞায়িত কোনও মানক পদ্ধতি নেই অপরিবর্তিত আচরণের সাথে আচরণ করার of