স্ট্যাক আনওয়াইন্ডিং কি? এর মাধ্যমে অনুসন্ধান করা হলেও আলোকিত উত্তর খুঁজে পেল না!
স্ট্যাক আনওয়াইন্ডিং কি? এর মাধ্যমে অনুসন্ধান করা হলেও আলোকিত উত্তর খুঁজে পেল না!
উত্তর:
স্ট্যাক আনওয়াইন্ডিং সাধারণত ব্যতিক্রম হ্যান্ডলিংয়ের সাথে সম্পর্কিত হয়। এখানে একটি উদাহরণ:
void func( int x )
{
char* pleak = new char[1024]; // might be lost => memory leak
std::string s( "hello world" ); // will be properly destructed
if ( x ) throw std::runtime_error( "boom" );
delete [] pleak; // will only get here if x == 0. if x!=0, throw exception
}
int main()
{
try
{
func( 10 );
}
catch ( const std::exception& e )
{
return 1;
}
return 0;
}
এখানে বরাদ্দ হওয়া মেমরিটি pleak
কোনও ব্যতিক্রম ছুঁড়ে ফেললে নষ্ট হবে, অন্যদিকে বরাদ্দ হওয়া মেমরিটি যে কোনও ক্ষেত্রে ডেস্ট্রাক্টর s
দ্বারা যথাযথভাবে প্রকাশ করা হবে std::string
। স্ট্যাকে বরাদ্দকৃত অবজেক্টগুলি "আনওয়াউন্ড" হয় যখন সুযোগটি প্রস্থান হয় (এখানে স্কোপটি ফাংশনটির হয় func
)) এটি স্বয়ংক্রিয় (স্ট্যাক) ভেরিয়েবলের ডেস্ট্রাক্টরগুলিতে সংযোজনকারী কলগুলি সংকলক দ্বারা সম্পন্ন করা হয়।
এখন এটি একটি শক্তিশালী ধারণা যা আরআইআইআই নামক কৌশলটির দিকে পরিচালিত করে , এটি হ'ল রিসোর্স অ্যাকুইজিশন ইজ ইনিশিয়ালাইজেশন , যা আমাদের সি ++ তে মেমরি, ডাটাবেস সংযোগ, ওপেন ফাইল বিবরণী ইত্যাদির মতো সংস্থানগুলি পরিচালনা করতে সহায়তা করে।
এখন এটি আমাদের ব্যতিক্রমী সুরক্ষা গ্যারান্টি সরবরাহ করতে দেয় ।
delete [] pleak;
শুধুমাত্র যদি এক্স == 0 উপনিত
এই সমস্ত সি ++ এর সাথে সম্পর্কিত:
সংজ্ঞা : আপনি স্ট্যাটিক্যালি বস্তুগুলি তৈরি করতে (হ্যাপের মেমরিতে তাদের বরাদ্দের বিপরীতে স্ট্যাকের উপরে) এবং ফাংশন কলগুলি সম্পাদন করার পরে সেগুলি "স্ট্যাক আপ" হয়।
যখন কোনও সুযোগ (দ্বারা বিস্মৃত {
এবং কিছু }
থেকে) বের হয়ে আসে (ব্যবহারের মাধ্যমে return XXX;
, স্কোপের শেষে পৌঁছানো বা একটি ব্যতিক্রম ছুঁড়ে দেওয়া) সেই সুযোগের মধ্যে থাকা সমস্ত কিছু ধ্বংস হয়ে যায় (ধ্বংসকারীদের সমস্ত কিছুর জন্য ডাকা হয়)। স্থানীয় অবজেক্টগুলি ধ্বংস করার এবং ডেস্ট্রাক্টরদের কল করার এই প্রক্রিয়াটিকে স্ট্যাক আনওয়াইন্ডিং বলা হয়।
আপনার স্ট্যাক আনওয়াইন্ডিং সম্পর্কিত নিম্নলিখিত সমস্যাগুলি রয়েছে:
মেমরি ফাঁস এড়ানো (গতিযুক্তরূপে বরাদ্দকৃত কোনও কিছু যা কোনও স্থানীয় অবজেক্ট দ্বারা পরিচালিত হয় না এবং ডেস্ট্রাক্টরে পরিষ্কার করা হয় তা ফাঁস হয়ে যাবে) - দেখুন রাইআইআই নিকোলাই উল্লেখ করেছে , এবং বুস্ট :: স্কোপড_পিটারের জন্য ডকুমেন্টেশন বা বুস্ট :: মুটেক্স ব্যবহারের এই উদাহরণটি দেখুন :: স্কোপড_লক ।
প্রোগ্রামের ধারাবাহিকতা: সি ++ স্পেসিফিকেশন উল্লেখ করে যে কোনও বিদ্যমান ব্যতিক্রম পরিচালনা করার আগে আপনাকে কখনই কোনও ব্যতিক্রম ছুঁড়ে ফেলা উচিত নয়। এর অর্থ এই যে স্ট্যাকের unwinding প্রক্রিয়া একটি ব্যতিক্রম নিক্ষেপ না করা উচিত (হয় শুধুমাত্র কোড destructors মধ্যে নিক্ষেপ না করতে, অথবা destructors সবকিছু পারিপার্শ্বিক নিশ্চিত ব্যবহার try {
এবং } catch(...) {}
)।
যদি কোনও ডেস্ট্রাক্টর স্ট্যাক আনওয়াইন্ডিংয়ের সময় কোনও ব্যতিক্রম ছুঁড়ে ফেলে তবে আপনি অপরিজ্ঞাত আচরণের জমিতে পৌঁছান যা আপনার প্রোগ্রামটিকে অপ্রত্যাশিতভাবে (সবচেয়ে সাধারণ আচরণ) বা মহাবিশ্বকে শেষ করে দিতে পারে (তাত্ত্বিকভাবে সম্ভব তবে বাস্তবে এটি পর্যবেক্ষণ করা হয়নি)।
একটি সাধারণ অর্থে, একটি স্ট্যাক "আনওয়াইন্ড" একটি ফাংশন কল এবং স্ট্যাকের পরবর্তী পপিংয়ের সমাপ্তির সাথে অনেকটা সমার্থক।
তবে, বিশেষত সি ++ এর ক্ষেত্রে, স্টক আনওয়াইন্ডিংয়ের সাথে কীভাবে কোনও কোড ব্লক শুরু হওয়ার পরে বরাদ্দকৃত সামগ্রীর জন্য সি ++ ডাস্ট্রাক্টরদের কল করতে হয়। যে অবজেক্টগুলি ব্লকের মধ্যে তৈরি করা হয়েছিল সেগুলি তাদের বরাদ্দের বিপরীত ক্রমে deallocated হয়।
try
ব্লকগুলিতে বিশেষ কিছু নেই । যে কোনও ব্লকে বরাদ্দকৃত স্ট্যাক অবজেক্টগুলি (কিনা তা try
না) ব্লকটি প্রস্থান করার সময় আনইন্ডিংয়ের সাপেক্ষে।
স্ট্যাক আনওয়াইন্ডিং বেশিরভাগ সি ++ ধারণা, যখন তার পরিধিটি বাইরে বেরিয়ে আসে তখন স্ট্যাক-বরাদ্দকৃত বস্তুগুলি কীভাবে ধ্বংস হয় (সাধারণভাবে বা কোনও ব্যতিক্রমের মাধ্যমে) এটি নিয়ে কাজ করে।
বলুন আপনার কাছে কোডের এই খণ্ড রয়েছে:
void hw() {
string hello("Hello, ");
string world("world!\n");
cout << hello << world;
} // at this point, "world" is destroyed, followed by "hello"
আপনি এখনও এটি পড়েছেন কিনা আমি জানি না, তবে কল স্ট্যাকের উইকিপিডিয়ায় নিবন্ধটির একটি সুন্দর ব্যাখ্যা রয়েছে।
unwinding:
ডাকা ফাংশন থেকে ফিরে স্ট্যাকের উপরের ফ্রেমটি পপ করবে, সম্ভবত কোনও ফেরতের মান রেখে যাবে। প্রোগ্রামের অন্য কোথাও এক্সিকিউশনটি পুনরায় শুরু করতে স্ট্যাকের বাইরে এক বা একাধিক ফ্রেম পপ করার আরও সাধারণ কাজকে স্ট্যাক আনওয়াইন্ডিং বলা হয় এবং যখন স্থানীয়-বহিরাগত নিয়ন্ত্রণ কাঠামো ব্যবহার করা হয়, যেমন ব্যতিক্রম হ্যান্ডলিংয়ের জন্য ব্যবহৃত হয় তখন সম্পাদন করা আবশ্যক। এই ক্ষেত্রে, কোনও ফাংশনের স্ট্যাক ফ্রেমে ব্যতিক্রম হ্যান্ডলারগুলি নির্দিষ্ট করে এক বা একাধিক এন্ট্রি রয়েছে। যখন একটি ব্যতিক্রম নিক্ষেপ করা হয়, স্ট্যাকটি অযাচিত হয় যতক্ষণ না কোনও হ্যান্ডলার পাওয়া যায় না যা ছুঁড়ে দেওয়া ব্যতিক্রমের ধরণের হ্যান্ডেল (ধরা) প্রস্তুত হয়।
কিছু ভাষায় অন্যান্য নিয়ন্ত্রণ কাঠামো থাকে যা সাধারণ আনওয়াইন্ডিংয়ের প্রয়োজন। পাস্কাল একটি বিশ্বব্যাপী গেটো স্টেটমেন্টটিকে নিয়ন্ত্রিত ফাংশন থেকে বের করে এবং পূর্বে আহবান করা বাহ্যিক ফাংশনে নিয়ন্ত্রণ স্থানান্তর করতে অনুমতি দেয়। এই ক্রিয়াকলাপটি স্ট্যাকটি আনওয়াউন্ডের প্রয়োজন, ঘেরযুক্ত বাইরের ফাংশনের মধ্যে লক্ষ্য বিবরণীতে নিয়ন্ত্রণ স্থানান্তর করতে যথাযথ প্রসঙ্গটি পুনরুদ্ধার করার জন্য প্রয়োজনীয় যতগুলি স্ট্যাক ফ্রেম সরানো প্রয়োজন removing একইভাবে, সি এর সেটজ্যাম্প এবং লংজ্যাম্প ফাংশন রয়েছে যা অ-স্থানীয় গোটো হিসাবে কাজ করে। কমন লিস্প আনইন্ড উইন্ড-রক্ষা বিশেষ অপারেটরটি ব্যবহার করে স্ট্যাকটি আনওয়াউন্ড করা হয় তখন কী হবে তার নিয়ন্ত্রণের অনুমতি দেয়।
একটি ধারাবাহিকতা প্রয়োগ করার সময়, স্ট্যাকটি (যৌক্তিকভাবে) অযাচিত হয় এবং তারপরে ধারাবাহিকতার স্ট্যাকটি দিয়ে পুনরায় ঘুরিয়ে দেওয়া হয়। ধারাবাহিকতা বাস্তবায়নের একমাত্র উপায় এটি নয়; উদাহরণস্বরূপ, একাধিক, সুস্পষ্ট স্ট্যাক ব্যবহার করে, একটি ধারাবাহিকতার প্রয়োগ সহজেই তার স্ট্যাকটি সক্রিয় করতে পারে এবং একটি মানকে পাশ কাটাতে পারে। স্কিম প্রোগ্রামিং ল্যাঙ্গুয়েজ যখন ধারাবাহিকতা চালিত হয় তখন নিয়ন্ত্রণ স্ট্যাকের "আনওয়াইন্ডিং" বা "রিওয়ন্ডিং" এর নির্দিষ্ট পয়েন্টগুলিতে স্বেচ্ছাচারিত ঠুনকে সম্পাদন করতে দেয়।
পরিদর্শন [সম্পাদনা]
আমি একটি ব্লগ পোস্ট পড়েছিলাম যা আমাকে বুঝতে সাহায্য করেছিল।
স্ট্যাক আনওয়াইন্ডিং কি?
যে কোনও ভাষায় পুনরাবৃত্ত ফাংশন সমর্থন করে (যেমন ফোর্টরান and 77 এবং ব্রেনফ * সিকে বাদে বেশ কিছু) ভাষা রানটাইম বর্তমানে কোন ফাংশনগুলি সম্পাদন করছে তার একটি স্তূপ রাখে। স্ট্যাক আনওয়াইন্ডিং পরিদর্শন করার একটি উপায় এবং সম্ভবত এই স্ট্যাকটি সংশোধন করা।
আপনি এটি কেন করতে চান?
উত্তরটি সুস্পষ্ট বলে মনে হতে পারে তবে বেশ কয়েকটি সম্পর্কিত, তবুও কিছুটা আলাদা, এমন পরিস্থিতিতে যেখানে আনওয়াইন্ডিং দরকারী বা প্রয়োজনীয়:
- রানটাইম নিয়ন্ত্রণ-প্রবাহ প্রক্রিয়া হিসাবে (সি ++ ব্যতিক্রম, সি লংজ্যাম্প (), ইত্যাদি)।
- একটি ডিবাগারে, ব্যবহারকারীকে স্ট্যাকটি দেখানোর জন্য।
- কোনও প্রোফাইলে স্ট্যাকের নমুনা নিতে।
- প্রোগ্রাম থেকে নিজেই (স্ট্যাকটি দেখানোর জন্য ক্র্যাশ হ্যান্ডলারের মতো)।
এগুলির সূক্ষ্মভাবে বিভিন্ন প্রয়োজনীয়তা রয়েছে। এর মধ্যে কিছু পারফরম্যান্স-সমালোচনামূলক, কিছু নয়। কারও কারও জন্য বাইরের ফ্রেম থেকে নিবন্ধগুলি পুনর্গঠন করার দক্ষতার প্রয়োজন হয়, কারও কারও কাছে তা হয় না। তবে আমরা এক সেকেন্ডের মধ্যে intoুকিয়ে দেব।
আপনি এখানে সম্পূর্ণ পোস্ট খুঁজে পেতে পারেন ।
প্রত্যেকে সি ++ এ ব্যতিক্রম পরিচালনা সম্পর্কে কথা বলেছে। তবে, আমি মনে করি স্ট্যাক আনওয়াইন্ডিংয়ের জন্য আরও একটি ধারণা রয়েছে এবং এটি ডিবাগিংয়ের সাথে সম্পর্কিত। একটি ডিবাগারকে যখনই বর্তমান ফ্রেমের আগের ফ্রেমে যাওয়ার কথা হয় তখনই তাকে স্ট্যাক আনওয়ানডিং করতে হয় do যাইহোক, এটি এক ধরণের ভার্চুয়াল আনওয়াইন্ডিং হিসাবে যখন এটি বর্তমান ফ্রেমে ফিরে আসে তখন এটি রিওয়াইন্ড করা দরকার। এর উদাহরণ জিডিবিতে আপ / ডাউন / বিটি কমান্ড হতে পারে।
আইএমও, এই নিবন্ধের নীচের চিত্রটি সুন্দরভাবে পরবর্তী নির্দেশের পথে অনড়িত স্ট্যাকের প্রভাবটি ব্যাখ্যা করেছে (একবার ব্যতিক্রম ছুঁড়ে ফেলা হলে মৃত্যুদণ্ড কার্যকর করা হবে) যা:
ছবিটিতে:
দ্বিতীয় ক্ষেত্রে, যখন কোনও ব্যতিক্রম ঘটে, তখন ফাংশন কল স্ট্যাকটি ব্যতিক্রম হ্যান্ডলারের জন্য রৈখিকভাবে অনুসন্ধান করা হয়। অনুসন্ধানটি ব্যতিক্রম হ্যান্ডলারের সাথে অর্থাৎ main()
এনক্লোজিং try-catch
ব্লক দিয়ে ফাংশনে শেষ হয় তবে ফাংশন কল স্ট্যাক থেকে সমস্ত এন্ট্রি সরিয়ে নেওয়ার আগে নয়।
সি ++ রানটাইম থ্রো এবং ক্যাচের মধ্যে তৈরি সমস্ত স্বয়ংক্রিয় ভেরিয়েবলকে ডেসট্রাক্ট করে। এই সহজ উদাহরণে f1 () এর নীচে ছোঁড়া এবং প্রধান () ক্যাচগুলি, সেই ক্রমে স্ট্যাকের উপর B এবং A টাইপের অবজেক্ট তৈরি করা হয়। যখন f1 () নিক্ষেপ করে, বি এবং এ এর ধ্বংসকারীদের ডাকা হয়।
#include <iostream>
using namespace std;
class A
{
public:
~A() { cout << "A's dtor" << endl; }
};
class B
{
public:
~B() { cout << "B's dtor" << endl; }
};
void f1()
{
B b;
throw (100);
}
void f()
{
A a;
f1();
}
int main()
{
try
{
f();
}
catch (int num)
{
cout << "Caught exception: " << num << endl;
}
return 0;
}
এই প্রোগ্রামের আউটপুট হবে
B's dtor
A's dtor
এটি কারণ যখন এফ 1 () নিক্ষেপ করে তখন প্রোগ্রামটির কলস্ট্যাক
f1()
f()
main()
সুতরাং, যখন f1 () পপ করা হয়, স্বয়ংক্রিয় ভেরিয়েবল বি নষ্ট হয়ে যায় এবং তারপরে যখন চ () পপড হয় তখন স্বয়ংক্রিয় ভেরিয়েবল a নষ্ট হয়ে যায়।
আশা করি এটি সুখী কোডিংয়ে সহায়তা করবে!
যখন কোনও ব্যতিক্রম নিক্ষেপ করা হয় এবং নিয়ন্ত্রণ একটি ট্রায়াল ব্লক থেকে হ্যান্ডলারের কাছে চলে যায়, ট্রাই ব্লক শুরু হওয়ার পর থেকেই সি ++ রান টাইম নির্মিত সমস্ত স্বয়ংক্রিয় অবজেক্টের জন্য ডেস্ট্রাক্টরকে কল করে। এই প্রক্রিয়াটিকে স্ট্যাক আনওয়াইন্ডিং বলা হয়। স্বয়ংক্রিয় অবজেক্টগুলি তাদের নির্মাণের বিপরীত ক্রমে ধ্বংস হয়। (অটোমেটিক অবজেক্টস হ'ল স্থানীয় অবজেক্টস যা অটো বা রেজিস্ট্রার হিসাবে ঘোষিত হয়েছে, বা স্থির বা বহিরাগত হিসাবে ঘোষিত হয়নি whenever
সাবওজেক্টস বা অ্যারের উপাদানগুলির সমন্বিত কোনও অবজেক্ট নির্মাণের সময় যদি কোনও ব্যতিক্রম ছুঁড়ে দেওয়া হয়, তবে ব্যতিক্রম ছোঁড়ার আগে সফলভাবে নির্মিত সেই সাবওজেক্টস বা অ্যারে উপাদানগুলির জন্য কেবল ধ্বংসকারীদের ডাকা হয়। স্থানীয় স্ট্যাটিক অবজেক্টের জন্য একজন ডেস্ট্রাক্টর কেবল তখনই কল করা হবে যখন অবজেক্টটি সফলভাবে নির্মিত হয়েছিল constructed
জাভা স্ট্যাক আনওয়াইডিং বা আনবাউন্ডিং খুব গুরুত্বপূর্ণ নয় (আবর্জনা সংগ্রহকারী সহ)। অনেকগুলি ব্যতিক্রম হ্যান্ডলিং পেপারগুলিতে আমি এই ধারণাটি দেখেছি (স্ট্যান্ড আনওয়াইন্ডিং), বিশেষত সেই লিটারগুলি সি বা সি ++ এ ব্যতিক্রম হ্যান্ডলিংয়ের বিষয়ে ডিল করে। সঙ্গে try catch
ব্লক আমরা shouln't ভুলবেন: স্থানীয় ব্লক পরে সমস্ত বস্তু থেকে মুক্ত স্ট্যাক ।