প্রোগ্রাম লেখার সময় আমাদের ভ্যারিয়েবল নিয়েও কাজ করতে হয়। এজন্য আমাদের দরকার হলো মেমোরি ম্যানেজমেন্ট সিস্টেম। আমরা যে টাইপেরই ভ্যারিয়েবল নেই না কেন, তা আমাদের সিস্টেম কোন না কোন ভাবে তা ম্যানেজ করে। আমরা একটি ভ্যারিয়েবল যখন ডিক্লেয়ার করি তখন তা স্ট্যাক মেমোরি অথবা হিপ মেমোরিতে জমা হয়। আজকের আর্টিকেলে আমরা জানবো স্ট্যাক এবং হিপ মেমোরির পার্থক্য নিয়ে।
স্ট্যাক কি?
আমরা প্রথমে জেনে নেই স্ট্যাক কি? এটা হলো কম্পিউটার মেমোরির একটা বিশেষ জায়গা যা কোন ফাংশন দ্বারা (main() ফাংশন সহ) তৈরি টেম্পোররি বা অস্থায়ী ভ্যারিয়েবল কে জমা করে রাখে। স্ট্যাক হলো একটি LIFO (Last In First Out) ডাটা স্ট্রাকচার। মানে এখানে যাকে সবার শেষে রাখা হবে, বের করার সময় তাকে প্রধান্য দেয়া হবে।
স্ট্যাক মোমোরি যথেস্ট অপটিমাইজড্। CPU খুব দ্রুত এখানে কাজ করতে পারে। প্রতিবার যখন ফাংশনে একটা ভ্যারিয়েবল ডিক্লেয়ার করা হয় তখন একে স্ট্যাকে পুশ করা হয়। যখন ফাংশনটির কাজ শেষ হয়ে যায় তখন যতগুলো ভ্যারিয়েবল স্ট্যাকে পুশ করা হইছিলো তাদের ফ্রি করে দেওয়া হয়। যখন একটা স্ট্যাক ভ্যারিয়েবল ফ্রি হয় তখন ঐ স্পেসটা আরেকটি স্ট্যাক ভ্যারিয়েবল এর জন্য প্রস্তুত হয়ে যায়।
স্ট্যাক এ ভ্যারিয়েবল স্টোর করার সুবিধা হলো, মেমোরিটা আগে থেকেই রেডি করা থাকে। নিজের হাতে মেমোরি Allocate ,বা Free করতে হয় না। CPU স্ট্যাক মেমোরিতে খুব দ্রুত রিডিং এবং রাইটিং অপারেশন চালাতে পারে।
যখন একটা ফাংশন এর কাজ শেষ হয়ে যায়, তখন ঐ ফাংশন দ্বারা তৈরি সব ভ্যারিয়েবল অটোমেটিক পপ আউট হয়ে যায়।মানে দ্ড়ায় স্ট্যাক মেমোরি লোকাল প্রকৃতির। এটা প্রোগ্রামিং এ ভ্যারিয়েবল স্কোপিং অথবা লোকাল ভ্যারিয়েবল কন্সেপ্টের এর সাথে সামন্জস্যপূর্ন।
C প্রোগ্রামিং এ একটা সাধারন ভূল, যে কোন ফংশনে একটা স্ট্যাক ভ্যারিয়েবল তৈরি করে ফাংশনটির কাজ শেষ হওয়ার পর তা আবার এক্সেস করার চেস্টা করা।
স্ট্যাক মেমোরির আরেকটা গুরুত্বপূর্ন বিষয় হলো, এখানে ভ্যারিয়েবল এর সাইজ এর একটি নির্দিষ্ট লিমিট আছে। এর বেশি স্ট্যাক এ স্টোর করা যায় না। এই লিমিট OS ভেদে আলাদা হয়ে থাকে।
Code Example:
1 2 3 4 5 6 7 8 9 | #include <stdio.h> int *numberPointer(){ int stackVariable=9;//pushing a variable in stack return &stackVariable; //returning the address will occure a warning. } int main() { numberPointer(); return 0; } |
উপরের numberPointer() ফাংশনটি ভিতরে Allocate করা স্ট্যাক ভ্যারিয়েবল, “stackVariable” এর Address return করবে। যেহেতু “stackVariable” নামের ভ্যারিয়েবলটা ফাংশনটির ভিতরে স্ট্যাটিক্যালি ডিক্লেয়ার করা হয়েছে (লাইন ৩) তাই এই ভ্যারিয়েবলটা স্ট্যাক মেমোরিতে পুশ হবে, এবং প্রোগ্রামটি Exit করার সাথে সাথে ফ্রি হয়ে যাবে। যদি এখন আমরা কোডটা রান করাই তবে নিচের মতো একটা ওয়ার্নিং দেখতে পাবো। কারন ফাংশনটা যে এড্রেস রিটার্ন করবে সেই এড্রেসটা রিটার্ন করার পরই ফ্রি হয়ে যাবে।
1 2 3 4 5 6 7 | In function 'numberPointer': 4:12: warning: function returns address of local variable [-Wreturn-local-addr] return &stackVariable; //returning the address will occure a warning. ^ |
এখন একটা Overview করা যাক:
- ফাংশনে ভ্যারিয়েবল পুশ বা পপ করার উপর নির্ভর করে স্ট্যাক বর্ধিত বা সংকুচিত হতে পারে।
- নিজে নিজে মেমোরি ম্যানেজমেন্ট করার কোন প্রয়োজন নেই। ভ্যারিয়েবল নিজে নিজেই Allocate এবং ফ্রি হয়ে যাবে।
- স্ট্যাক এর সাইজ লিমিট রয়েছে।
- যে ফাংশনটি স্ট্যাক ভ্যারিয়েবল তৈরি করে, ঐ ফাংশনের লাইফটাইম যতক্ষন স্ট্যাকে ভ্যারিয়েবল এর অবস্থান ততক্ষন।
হিপ মেমোরি কি?
হিপ হলো কম্পিউটার মেমোরির একটি জায়গা যেখানে আমাদের জন্য আগে থেকেই মেমোরি ম্যানেজ করা থাকে না, বা CPU নিজেও অটোমেটিক্যালি ম্যানেজ করে না। এটি মেমোরির একটি বিশাল অঞ্চল জুরে থাকে। হিপ (Heap) এ মেমোরি Allocation করার জন্য আমরা malloc বা calloc নামের C এর Built in functions ব্যবহার করে থাকি। একবার আপনি হিপ এ মেমোরি Allocation করলে একে কাজ শেষে ফ্রি ( free() ) করার দ্বায়িত্বটাও আপনার ঘাড়ে। কাজটা ঠিক মতো না করতে পারলে আপনার প্রোগ্রামে মেমোরি লিক এর মতো সিচুয়েশন তৈরি হবে। মেমোরি লিক(Memory leak) একটা সিরিয়াস সমস্যা মূলত সেই ধরনের সফটওয়্যার এর জন্য যা অনেক সময় ধরে রান করে।
হিপে মূলত কোন সাইজ লিমিট নেই, যেমনটা স্ট্যাক এর ক্ষেত্রে দেখা যায়। হিপ মেমোরিতে Read এবং Write অপারেশন একটু স্লো। কারন হিপ মেমোরি Access করতে পয়েন্টার ব্যবহার করতে হয়। স্ট্যাকের বিপরীতে, হিপ মেমোরিতে তৈরি করা ভ্যারিয়েবল প্রোগ্রাম এর যেকোন জায়গা থেকেই Access করা যায়।
Code Example:
1 2 3 4 5 6 7 8 9 10 | #include <stdio.h> #include <stdlib.h> int *numberPointer(){ int *heapVariable = (int*) malloc(sizeof(int)); return heapVariable; } int main() { numberPointer(); return 0; } |
উপরে যে কোডের উদাহরণ দেয়া হয়েছে, তা রান করালে কোন ধরনের Warning দিবে না। কারন এখানে আমরা যে মেমোরিটা Allocate করেছি তা হিপে Allocate হয়েছে (লাইন ৪)। তাই ফাংশনটি যদি Exit হয়েও যায় তবুও আমাদের কাছে address টা Available থাকবে।
স্ট্যাক মেমোরি বনাম হিপ মেমোরি
স্ট্যাক মেমোরি
- খুব দ্রুত এক্সেস করা যায়।
- নিজে নিজে ভ্যারিয়েবল ফ্রি করার দরকার নেই।
- CPU এর দাড়াই স্পেস ম্যানেজ করা হয়।
- শুধু মাত্র লোকাল ভেরিয়েবল এর জন্য
- স্ট্যাক সাইজে লিমিট আছে।
- ভ্যারিয়েবল রিসাইজ করা যায় না।
হিপ মেমোরি
- ভ্যারিয়েবল গুলোকে গ্লোবালি এক্সেস করা যায়। (কোন ভাবে এড্রেস পাস করে হলেও)
- মেমোরি সাইজে লিমিট নেই।
- স্ট্যাক এর চেয়ে স্লো।
- স্পেস এর সর্বোত্তম ব্যবহার এর কোন গেরান্টি নেই 😉
- নিজে নিজেই ম্যানেজ করতে হবে।
- ভ্যারিয়েবল গুলো realloc() ব্যবহার করে resize করা যায়।
For further reading . Wikipedia
ডাটা স্ট্রাকচার: সেগমেন্ট ট্রি লেজি প্রপাগেশন।
প্রোগ্রামিংঃ টেইল কল রিকার্শন অপটিমাইজেশন টেকনিক ।
আজকের পোস্টের টপিক মুলত আরেকটা করতে চেয়েছিলাম। কিন্তু ঐটা লিখতে গিয়ে মনে হলো তার আগে Data structure এ Stack এবং Queue বিষয়গুলা আগে জানা দরকার। ঐটা লিখতে গিয়ে আরেকটা ঝামেলা হলো। পোস্টের কোড Example বানাতে গিয়ে দেখলাম, এখানে সামান্য ভূলেই রানটাইম এরর এর সম্ভাবনা আছে। তাই এরও আগে মেমোরি ম্যানেজমেন্ট নিয়ে বুঝতে হবে। তাই এইটা লিখলাম। আর্টিকেলটা কেমন হলো কমেন্টে জানাবেন। কোন লাইনে ভূল হলে দয়া করে ধরিয়ে দিবেন। Good bye.
ধন্যবাদ। শীঘ্রই Stack এবং Queue নিয়ে লেখাটি দেখার আশা করছি।
শিঘ্রই পেয়ে যাবেন লেখাটি। ধন্যবাদ ❤️
Great 💜
Thanks bro ❤️
আচ্ছা STL. এর কিছু কিছু ফাংশন গুলা একই কাজ করার সর্তেও নাম ভিন্ন কেন হয়।যেমন vector এ আমরা push_back() ফাংশন ব্যবহার করি আর stack or Queue তে সেটা শুধু push()। কিন্তু তাদের কাজ একই।এই ভিন্নতা করার কি দরকার ছিলো।😑😑😑
এই বিষয় নিয়ে আমার কাছে কোন ভালো উত্তর নেই।
তবে যেহেতু আমরা ভেক্টরের যেকোন পজিশনে মান ঢুকাতে পারি, তাই push_back() এক্ষেত্রে আমাদের পরিষ্কার করে দেয় যে, এর মাধ্যমে ভেক্টর এ ঢুকানো মানটি ভেক্টর এর পেছনে রাখা হবে।
অপরদিকে স্ট্যাক বা কিউ তে মানগুলো শুধুমাত্র পেছনেই রাখতে পারি। তাই আমার ধারনা এক্ষেত্রে push() ব্যবহার করাই যুক্তিযুক্ত।
-ধন্যবাদ।
❤️
Thank You