C++ এ ডায়নামিক মেমরি বরাদ্দ

C E Dayanamika Memari Baradda



সাধারণত, C++ প্রোগ্রামিং ল্যাঙ্গুয়েজে সোর্স কোড ব্যবহার করার সময়, একটি কম্পাইলার ডেটা স্টোরেজের জন্য ভেরিয়েবলের জন্য ম্যানুয়ালি মেমরি বরাদ্দ করে। এটা স্ট্যাটিক মেমরি একটি বরাদ্দ বলা হয়. এটি একটি নির্দিষ্ট মেমরি যা একবার ঘোষণা করা হলে পরিবর্তন করা যায় না। এই ধরনের মেমরি বরাদ্দের জন্য, অপারেটিং সিস্টেম ডেটা সঞ্চয় করার জন্য স্ট্যাক ব্যবহার করে। স্ট্যাটিক অ্যালোকেশনে, সোর্স কোডটি কার্যকর করা শুরু করার আগে মেমরি বরাদ্দ করা হয়।

যেখানে, গতিশীল মেমরি বরাদ্দকরণে, মেমরিটি বরাদ্দ করা হয় যখন সম্পাদন শুরু হয়। এই মেমরি রান-টাইমে প্রোগ্রামার দ্বারা ম্যানুয়ালি বরাদ্দ করা হয়, এটি C++ এ রান-টাইম মেমরি বরাদ্দ হিসাবেও পরিচিত। ডায়নামিক মেমরির আকার প্রোগ্রামের যেকোনো অবস্থানে পরিবর্তন করা যেতে পারে কারণ ঘোষণার সময়, আমরা এমন একটি আকার উল্লেখ করি না যা স্থির করা যেতে পারে। আমরা শুধুমাত্র ভেরিয়েবলে সরাসরি মান প্রদান করি।

সাধারণ ভেরিয়েবলের সাথে মেমরি বরাদ্দের পার্থক্য

সাধারণ ভেরিয়েবলে, একটি কম্পাইলার দ্বারা বরাদ্দ করা মেমরিটি স্বয়ংক্রিয়ভাবে বরাদ্দ এবং ডিললোকেট হয়। যখন প্রোগ্রামার দ্বারা মেমরিটি গতিশীলভাবে বরাদ্দ করা হয়, তখন তাকে মেমরিটি সরিয়ে ফেলতে হবে বা ডিলোকেট করতে হবে যখন এটি সোর্স কোডের পরবর্তী সম্পাদনে কোন কাজে আসে না। এই পরিস্থিতি একটি 'মেমরি লিক' ঘটায় যখন প্রোগ্রামটি বন্ধ হয়ে যায় যখন মেমরিটি ডিলোকেটেড না হয়।







গতিশীল বরাদ্দের জন্য অপারেটর

C++ এ, দুটি অপারেটর মেমরি বরাদ্দ এবং ডিলোকেশনে সাহায্য করে: 'নতুন' এবং 'মুছুন' যেগুলি আরও ভাল উপায়ে মেমরির বরাদ্দ এবং ডিলোকেশনের জন্য ব্যবহৃত হয়।



নতুন অপারেটর

এটি মেমরি বরাদ্দের দাবিকে বোঝায়। নতুন অপারেটর মেমরি শুরু করে এবং পর্যাপ্ত মেমরি উপলব্ধ থাকলে পয়েন্টার ভেরিয়েবলে সেই বরাদ্দ করা মেমরির ঠিকানা ফেরত দেয়।



পয়েন্টার অবজেক্ট = নতুন তথ্য - প্রকার ;

অপারেটর মুছুন

ঠিক নতুন অপারেটরের মতো, একটি ডিলিট অপারেটর বরাদ্দ করা মেমরি অপসারণ করতে ব্যবহৃত হয়। C++ এ, প্রোগ্রামার ডিললোকেশনের জন্য এই অপারেটর ব্যবহার করতে পারে।





# পয়েন্টার_ভেরিয়েবল মুছুন;

উদাহরণ 1

এই উদাহরণে, আমরা দুটি পয়েন্টার প্রবর্তন করব: একটি হল একটি পূর্ণসংখ্যা টাইপ পয়েন্টার এবং অন্যটি একটি ফ্লোট পয়েন্টার। পয়েন্টারগুলি তাদের সাথে একটি তারকাচিহ্ন চিহ্ন ব্যবহার করে শুরু করা হয়।

# Int * pointInt;
# ফ্লোট * পয়েন্টফ্লোট;

এই দুটি প্রিন্টার ব্যবহার করে, আমরা গতিশীলভাবে মেমরি বরাদ্দ করব।



গতিশীল বরাদ্দকরণে পয়েন্টারগুলির ভূমিকা:
স্টোরেজ স্পেসের মেমরি ব্লক আকারে বিকশিত হয়। যখনই আমরা কোন প্রোগ্রাম এক্সিকিউট করি বা কোন অপারেশন করি তখন সেই নির্দিষ্ট উদ্দেশ্যে মেমরি বরাদ্দ করা হয়। সেই মেমরিটির একটি বিশেষ ঠিকানা রয়েছে যা প্রোগ্রামের সাথে যুক্ত যা সনাক্ত করে যে কোন প্রক্রিয়া বা প্রোগ্রামটি সেই মেমরিতে অনুমোদিত। যেকোন মেমরি স্লট ঠিকানার মাধ্যমে অ্যাক্সেস করা হয়। তাই এই ঠিকানা পয়েন্টার মাধ্যমে সংরক্ষণ করা হয়. সংক্ষেপে, আমাদের মেমরি অ্যাক্সেস করতে এবং একইভাবে যেকোন কাজের জন্য মেমরির একটি নির্দিষ্ট অংশ বরাদ্দ করার জন্য আমাদের পয়েন্টার প্রয়োজন। ঠিকানা সংরক্ষণ করার জন্য পয়েন্টার প্রয়োজন।

যেহেতু 'নতুন' কীওয়ার্ডটি ম্যানুয়াল বরাদ্দে মেমরির গতিশীল বরাদ্দের জন্য ব্যবহৃত হয়, মেমরিটি কম্পাইলার দ্বারা বরাদ্দ করা হয়। আমাদের রান টাইমে মেমরি বরাদ্দ করার দরকার নেই। কিন্তু যেহেতু গতিশীল বরাদ্দ র্যান্ডম, তাই আমাদের পয়েন্টার সনাক্ত করতে হবে এবং বাঁধাই প্রক্রিয়ার জন্য, এই নতুন অপারেটরটি ব্যবহার করা হয়।

# বিন্দু = new int;

একইভাবে, ভাসমান পয়েন্টার একইভাবে আবদ্ধ। বাইন্ডিং প্রক্রিয়ার পরে, আমরা যে কোনো অপারেশনের জন্য যে মেমরি বুক করতে চাই তার কোনো মান নির্ধারণ করব। পয়েন্টার ঘোষণা করে, আমরা মেমরিতে একটি নির্দিষ্ট মান নির্ধারণ করি।

# *pointInt = 50;

পয়েন্ট ফ্লোটের জন্য একটি ফ্লোট মানও ঘোষণা করা হয়। বরাদ্দ করার পরে মানগুলি প্রদর্শন করুন।

যেমনটি আমরা আলোচনা করেছি, 'নতুন' অপারেটর বরাদ্দ করতে ব্যবহৃত হয় যখন 'মুছে ফেলা' মেমরি ডিলোকেট করতে ব্যবহৃত হয়। সুতরাং একবার আপনি কোডে টাস্ক বা অপারেশন সম্পন্ন করলে, আমরা টাস্কের জন্য বরাদ্দ করা মেমরিটি সরিয়ে ফেলব।

মেমরির সেই অংশটি ডিলোকেট করা ভাল যাতে অন্য কোনও প্রক্রিয়া এটি ব্যবহার করতে পারে। আমরা উভয় পয়েন্টারের জন্য এই বরাদ্দ প্রয়োগ করব।

পয়েন্ট মুছুন ভাসা ;

একবার আপনি টেক্সট এডিটরে কোডটি সেভ করলে, উবুন্টু টার্মিনাল আপনাকে একটি g++ কম্পাইলারের মাধ্যমে ফাইলের ভিতরে সোর্স কোড চালানোর অনুমতি দেয়।

$g++ -o mem mem.c
$./মেম

কার্যকর করার পরে, আপনি মেমরিতে নির্ধারিত মানগুলি দেখতে পাবেন।

উদাহরণ 2

এই উদাহরণ ব্যবহারকারীর মিথস্ক্রিয়া জড়িত আছে. আমরা একটি সংখ্যা ভেরিয়েবল নেব যাতে ব্যবহারকারীর কাছ থেকে একটি মান থাকবে। এই প্রোগ্রাম শিক্ষার্থীদের জিপিএ ফলাফল সংরক্ষণ করবে। রান টাইমে সমস্ত ফলাফল সংরক্ষণ করা হবে।

ব্যবহারকারী যখন ছাত্র সংখ্যা প্রবেশ করে, মেমরি প্রতিটি সংখ্যার বিপরীতে বরাদ্দ করা হয়। একটি ফ্লোট টাইপ পয়েন্টার এখানে শুরু করা হয়েছে যা ফলাফলের মেমরি বরাদ্দে ব্যবহার করা হবে।

আমরা পয়েন্টারটিকে ফ্লোটে নিই যেহেতু GPA দশমিক স্বরলিপিতে রয়েছে। আমরা জিপিএ-র জন্য একটি পয়েন্টার টাইপ অ্যারে নিই কারণ এটি অনেক শিক্ষার্থীর জন্য ফলাফল করতে পারে।

Ptr = নতুন ভাসা [ একের উপর ]

'নতুন' কীওয়ার্ড সহ এই পয়েন্টার অ্যারেটি মেমরির সাথে এক্সিকিউশনকে আবদ্ধ করবে। প্রতিটি শিক্ষার্থীর জন্য জিপিএ প্রবেশ করানো হবে। যেহেতু আমরা ব্যবহারকারী যোগ করতে চায় সেই সংখ্যার সাথে পরিচিত নই, আমরা প্রবেশ করা নম্বর পর্যন্ত জিপিএ প্রবেশ করার জন্য একটি লুপ ব্যবহার করেছি। লুপের প্রতিটি পুনরাবৃত্তিতে, ব্যবহারকারীকে শিক্ষার্থীকে চিহ্নিত করে ফলাফল লিখতে জিজ্ঞাসা করা হয়। ফলাফল সংরক্ষিত হয়ে গেলে, আমরা আবার একটি লুপ ব্যবহার করব যাতে শিক্ষার্থীদের সমস্ত জিপিএ দেখানো হয়। শেষ পর্যন্ত, পয়েন্টার টাইপ অ্যারে মুছে ফেলা হয়, কারণ গতিশীল স্টোরেজের উদ্দেশ্যটি সম্পন্ন হয়েছিল।

মুছে ফেলা [ ] ptr ;

এখন আমরা উপরে উল্লিখিত কোডটি কার্যকর করব। ব্যবহারকারীকে প্রথমে শিক্ষার্থীর সংখ্যা লিখতে অনুরোধ করা হবে। তারপর প্রতিটি শিক্ষার্থীর জিপিএ প্রবেশ করানো হবে।

উদাহরণ 3

এই উদাহরণটি ক্লাসের অবজেক্টের জন্য নতুন এবং ডিলিট অপারেটর ব্যবহার করে। এই শ্রেণীতে পূর্ণসংখ্যার প্রকারের একটি ব্যক্তিগত ভেরিয়েবল রয়েছে যা বয়স সংরক্ষণ করে। একটি ক্লাসের সর্বজনীন অংশে, কনস্ট্রাক্টর তৈরি করা হয় যা বয়সটিকে একটি সংখ্যা '10' এ শুরু করবে। এখানে আরেকটি ফাংশন ব্যবহার করা হয়েছে যা কনস্ট্রাক্টরে আরম্ভ করা বয়স প্রদর্শন করবে।

এখন আমরা গতিশীল বরাদ্দের জন্য মূল প্রোগ্রামের দিকে যাব। ক্লাসের বস্তুটি গতিশীলভাবে তৈরি করা হয়।

ছাত্র * ptr = নতুন ছাত্র ( ) ;

যখন বস্তুটি গঠিত হয়, কনস্ট্রাক্টর স্বয়ংক্রিয়ভাবে প্রয়োগ করা হবে। বয়স জানতে একটি ফাংশন কল করা হবে। এটি ptr এর মাধ্যমে করা হবে।

Ptr - > বয়স ( ) ;

এবং শেষে, স্মৃতি মুক্তি পাবে।

উপসংহার

কম্পাইলার দ্বারা চিহ্নিত নির্দিষ্ট স্টোরেজের পরিবর্তে প্রোগ্রামার দ্বারা রান টাইম এক্সিকিউশনে ডায়নামিক মেমরি বরাদ্দ করা হয়। এই বরাদ্দ একটি এলোমেলো ভিত্তিতে এবং এটি ব্যবহার করার পরে নির্মূল করা যেতে পারে। যখন, বেশিরভাগ ক্ষেত্রে, অপসারণের আগে, কার্যকর করার প্রক্রিয়া বন্ধ হয়ে যায় এবং এই গতিশীল বরাদ্দের ফলে মেমরি লিক হয়ে যায়। আমরা C++ প্রোগ্রামিং ল্যাঙ্গুয়েজ ব্যবহার করে উবুন্টু লিনাক্স সিস্টেমে বিভিন্ন পদ্ধতিতে এই ঘটনাটি বাস্তবায়ন করেছি।