Sunday, October 15, 2017

C# For Beginners , Part - 28 ( Heap & Stack Memory,Difference Between Classes & Structs )

আমরা , আজকে মেমোরী'র দুইটি অংশ  Stack & Heap  নিয়ে কথা বলবো ।। তার আগে , আমরা চলো আগে একটা ছবি দেখে আসি ------------------------




Stack & Heap  নামে মেমোরী'র দুইটি অংশই আমাদের কম্পিউটারের র‍্যামে সংরক্ষিত ।। এখন একটা জিনিস খুবই গুরুত্বপূর্ণ  সেটা হলো -- static memory allocation এর জন্য
Stack ইউজ করা হয় ।। আর , dynamic memory allocation এর জন্য Heap ইউজ করা হয় ।। আমরা , যতো রকমের ফাংশন লিখি , বা ভ্যারিয়েবল ডিক্লেয়ার করি ( int x,double y,etc..) , সব কিছু  এই স্ট্যাক মেমোরিতে স্টোর হয় এবং সকল ধরনের এক্সিকিউশন এই মেমোরিতেই হয় ।। আমরা একটা কোড লিখার পর , যখন সেটা কম্পাইল করা হয় , তখনই সবকিছুর আধার হিসেবে কাজ করে এই স্ট্যাক মেমোরী ।। 

   কিন্তু , যখন প্রোগ্রাম'টি রান করানো হয় --- তখন যদি , কখনো dynamic memory allocation   এর প্রয়োজন পরে , তখন প্রোগ্রামটি তার চলাকালীন সময়ে হিপ মেমোরি'র জায়গা দখল করে ।।

 তোমার যদি কোড লিখার সময়ই , জানা থাকে তোমার প্রোগ্রাম কতটুকূ জায়গা খাবে ও তোমার ডেটা'র জায়গা বেশি বড়ো না হয়ে থাকে  ??? তাহলে তুমি স্ট্যাক ইউজ করতে পারবা ।। 

কিন্তু , তুমি যদি না জেনে থাকো তোমার প্রোগ্রাম কতটুকু জায়গা খাবে ?? অর্থাৎ  প্রোগ্রামটি চলাকালীন সময়ে , তার কারযপরিধি বা ডেটা'র পরিমাণ বাড়াতে চায় , তখন তোমায় হিপ মেমোরী'র বযবস্থা রাখতে হবে ।। এটাকে , ভার্চুয়াল মেমোরি বলা হয় , যেটা প্রোগ্রাম চলাকালীন তার রানটাইমে মেমোরি এলোকেট করতে ইউজ করে ।। তবে একটাই সমস্যার কথা , সেটা হলো - হিপ মেমোরি অ্যাকসেস করা , স্ট্যাক মেমোরী'র এর থেকে কিছুটা স্লো ।। 

যাই হোক , এখন আসি -- আরেকটা গুরুত্বপূর্ণ বিষয়ে সেটা হলো , রেফারেন্স টাইপ ও ভ্যালু টাইপ ।। খুব ভালো করে তোমায় বুঝতে হবে বিষয়টা ।। তুমি যে , নরমালি একটা ইন্টিজার ভ্যারিয়েবল ডিক্লেয়ার করো , সেটা সাধারনত সেই ডেটাটাইপের ভ্যালু স্টোর করে , এখান থেকেই এর নাম হয়েছে ভ্যালু টাইপ  ।। আচ্ছা , এটা কিভাবে কাজ করে ??? 


    int x লিখা মানে , স্ট্যাক এ  x নামে একটা চার বাইটের মেমোরি এলোকেট হয় । ব্যাস          এইটুকুই ।।  এটা হলো ভ্যালু টাইপ ।।

 কিন্তু , তুমি যখন একটা অবজেক্ট ক্রিয়েট করবা , তখন কি হয় ???? ধরো , তুমি
Form1 নামে একটা ক্লাসের অবজেক্ট ক্রিয়েট করলা ।।

               Form1  frm = new Form1();          

তাহলে ,new Form1() দ্বারা আমরা একটা অবজেক্ট ক্রিয়েট করলাম , হিপ মেমোরিতে ।। 
আর ,  frm  নামের একটা ভ্যারিয়েবল ক্রিয়েট করলাম , এইটা হিপ মেমোরিতে থাকা Form1
ক্লাসের যে অবজেক্ট খুললাম  , তার মেমোরি'র  অ্যাড্রেস  স্টোর করে রাখে ।। এটা মাথায় ঠিকভাবে রাখা উচিত , এই frm  নামের ভ্যারিয়েবল Form1 ক্লাসের যে অবজেক্ট আছে তার কোনো ডেটা কিন্তু স্টোর করে না , এটা শুধু সেই অব্জেক্ট এর মেমোরী'র অ্যাড্রেস স্টোর করে রাখে ।।  frm আসলে একটা পয়েন্টার ভ্যারিয়েবল , এটা মেমোরি'র অ্যাড্রেস পয়েন্ট করে ।। 

তো যাই হোক , আমরা নরমাল যে ডেটাটাইপ গুলো দিয়ে ভ্যারিয়েবল ডিক্লেয়ার করি , সেগুলো 
সবগুলোই তাদের ডেটাটাইপ অনুসারে ভ্যালু স্টোর করে , তাই এগুলোকে ভ্যালু টাইপ ভ্যারিয়েবল
বলা হয় ।।  আর , আমরা অব্জেক্ট ক্রিয়েট করবার সময় , যে -- ভ্যারিয়েবল ক্রিয়েট করি , সেই সবগুলিই শুধু সেই অব্জেক্ট এর রেফারেন্স ( অ্যাড্রেস ) স্টোর করে , তাই এগুলোকে রেফারেন্স 
ভযারিয়েবল বলা হয় ।। 

আশা করি , এই বিষয়টা একদম ক্লিয়ার । তারপরো যদি , খটকা লাগে , তাহলে পুরোটা আরো একবার পড়ে নাও ।।



       আচ্ছা এবার আমরা , স্ট্রাকট ও ক্লাসের ডিফারেন্স নিয়ে কথা বলবো ।। 

১) স্ট্রাকচার ক্রিয়েট করলে , সেটা স্ট্যাক মেমোরিতে স্টোর হয় ।। আর ক্লাস এর  ক্ষেত্রে অব্জেক্ট  হিপ  মেমোরিতে স্টোর হয় ।। 

২) স্ট্রাকচার ভ্যালু টাইপ , আর ক্লাসে হলো রেফারেন্স টাইপ ।। 

৩) একটা শূন্য স্ট্রাকচার  মেমোরিতে কোনো জায়গা দখল করে না ।। বাট , একটা শুণ্য ক্লাস  মে্মোরিতে এক বাইট জায়গা দখল করে ।। 

৪) স্ট্রাকচারের ক্ষেত্রে ,ইনহেরিটেন্স ঘটে না - এর মানে স্ট্রাকচার কে কখনো বেইস স্ট্রাকচার হিসেবে - আর কোনো স্ট্রাকচার ক্রিয়েট করা যাবে না ।। কিন্তু , ক্লাসের ক্ষেত্রে ইনহেরিটেন্স সাপোর্ট করে ।। 

৫) তুমি যখন , একটা স্ট্রাকচার থেকে আরেকটা স্ট্রাকচার কপি করবা , তখন পুরো স্ট্রাকচারের একটা কপিই ক্রিয়েট হয় , মেমোরিতে ।। কিন্তু , তুমি যখন একটা ক্লাস এর কপি করো , তখন কিন্তু পুরো ক্লাস আর কপি হয় না , শুধু নতুন একটা রেফারেন্স ভ্যারিয়েবলই ক্রিয়েট হয় , যেটা ঐ ক্লাস এর অব্জেক্ট এর মেমোরী'র অ্যাড্রেস স্টোর করে ।। চলো , একটা উদাহরন দেখে আসি ---


using System;

public class student

{
   public string name;
   public   int id;

    public void print()
    {
        Console.WriteLine("Student's Name {0} , ID No .  = {1} ", this.name, this.id);
    }
   
}

public class Program
{
    public static void Main()


    {


        student s = new student();
        s.name = "Joy";
        s.id = 101;


        student a = s;
        a.id=100;
        a.name = "JOYA";


        s.print();  


        Console.ReadKey();


    }
}

আমরা , এখানে
student s রেফারেন্স ভ্যারিয়েবল ক্রিয়েট এর পরেও , আরো একটা রেফারেন্স ভ্যারিয়েবল ক্রিয়েট করে প্রথমটা থেকে কপি করে নিলাম student a = s;student a = s ।।  তাহলে ,  আসলে কি হলো ??? তুমি , সেই একই  student ক্লাসের অ্যাড্রেস ,এবার a নামক রেফারেন্স ভ্যারিয়েবলে অ্যাসাইন করে নিলে ।। এর মানে , a দিয়েও তুমি ওই student ক্লাসের অব্জেক্ট এর 
ডেটা চেইঞ্জ করতে পারবা , আর  S দিয়ে তো পারবেই ।।


৬) ক্লাসের ডিস্ট্রাক্টর থাকতে পারে , বাট স্ট্রাকচার এর কোনো ডিস্ট্রাক্টর নেই ।।

৭) ক্লাসের পযারামিটারলেস কনস্ট্রাকটর থাকতে পারে , বাট স্ট্রাকচার এর থাকে না ।।
চলো , একটু উদাহরণ দেখে আসি --------------------------------------

using System;

public class student

{
   public string name;
   public   int id;
    public student()
    {

     }
  
   
}

public class Program
{
    public static void Main()
    {
        Console.ReadKey();
    }
}

এই কোড'টাকে রান করাও , কোনো আওউটপুট  কন্সল স্ক্রিনে দেখতে পাবে না , কারণ আমি কিছু লিখি নি ।। কিন্তু , বিল্ড করার সময় কোনো এরর পাবা না ।।আমরা , এখানে -- প্যারামিটারলেস কনস্ট্রাকটর ক্রিয়েট করেছি ।। কিন্তু , উপরের কোড'টাই জাস্ট class এর যায়গায় শুধু  struct দিয়ে লিখো ।। দেখবা , রান করাতেই পারবা না , এরর খাবা ।।


আচ্ছা , আমরা তো এটা  জানি যে - স্ট্রাকচার থেকে ডিরাইভড স্ট্রাকচার বের করা যায় না ।। এখন আমি যদি চাই যে - আমি ক্লাসকে এমন বযবস্থা করতে চাই , যেনো - সেই ক্লাস থেকেওন্য কেউ আর কোনো ক্লাস ইনহেরিট করতে না পারে ।। তাইলে কিভাবে করবো ?? বলো তো -----------------------

using System;

public sealed class student

{
   public string name;
   public   int id;
    public student()
    {

     }
  
   
}


public class Program
{
    public static void Main()
    {
       
       
        Console.ReadKey();
    }
}

তাহলে , তুমি যদি কোনো ক্লাসের আগে , sealed কিওয়ারড ইউজ করো , তাহলে - সেই ক্লাস থেকে অনয কোনো ক্লাস ডিরাইভড হবে না ।।

স্ট্রাকচারও  প্রকৃতপক্ষে উপরের ক্লাসের মতোই অটোমেটিক sealed টাইপস ।। তাই , স্ট্রাকচার থেকে ইনহেরিটেড করা যায় না ।। আজ এইটুকুই ------------------------






s











No comments:

Post a Comment