C/সি প্রোগ্রামিং এ ডাইনামিক মেমরি এলোকেশন

রানটাইমে মেমরি এলোকেট করার প্রসেসকে ডাইনামিক মেমরি এলোকেশন বলে।

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

সি প্রোগ্রামিং stdlib.h এ চারটি লাইব্রেরী ফাংশন রয়েছে যে গুলো দিয়ে আমরা ডাইন্যামিকেলি মেমরি এলোকেট করতে পারি। ফাংশন গুলো হচ্ছেঃ

* malloc()
* calloc()
* free()
* realloc()

 

সবার আগে free ()এর কাজ বলে নি। free নাম থেকেই বুঝা যায় এটা দিয়ে এলোকেটকৃত মেমরি মুক্ত/dellocate করে দেওয়া হয়।

malloc() ব্যবহারের সিনট্যাক্সঃ

var = malloc(byte-size)

যদি আমাদের র‍্যামে মেমরি এলোকেট করার মত মেমরি না থাকে, তাহলে এলোকেশন করতে পারবে না। এবং একটা নাল পয়েন্টার রিটার্ন করবে। যদিও এখনকার কম্পিউটারে এ সমস্যা হওয়ার কথা না… যথেষ্ট র‍্যাম থাকে। একটি উদাহরণঃ


#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main()
{
char *dynamic_var;

dynamic_var = malloc( 200 * sizeof(char) );

if( dynamic_var== NULL )
{
printf("Couldn't able to allocate requested memory\n");
}
else
{
strcpy( dynamic_var,"Dynamically allocated string.");
}
printf("%s\n", dynamic_var );

free(dynamic_var);

return 0;
}

dynamic_var নামে একটি ডাইনামিক ভ্যারিয়েবল নিয়েছি। যার কোন সাইজ আমরা সেট করে দি নাই। আমরা malloc দিয়ে এই dynamic_var এর সাইজ সেট করেছি। if else দিয়ে আমরা dynamic_var চেক করে নিয়েছি। যদি মেমরি এলোকেট করতে না পারে, তাহলে আমাদের লেখা উঠবে “Couldn’t able to allocate requested memory” আর যদি মেমরি এলোকেট করতে পারে, তাহলে strcpy স্ট্রিং ফাংশন ব্যবহার করে dynamic_var এ Dynamically allocated string. এ স্ট্রিংটি এসাইন করবে। এরপর আমরা dynamic_var ভ্যারিয়েবলটি প্রিণ্ট করেছি।

শেষে free ব্যবহার করে এলোকেটকৃত মেমরি মুক্ত করে দিয়েছি।

আরেকটা উদাহরণ দিচ্ছিঃ


#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main()
{
int *dynamic_var;
int n,i;
printf("How many number you will store? ");
scanf("%d",&n);

dynamic_var = malloc( n * sizeof(int) );
if( dynamic_var== NULL )
{
printf("Couldn't able to allocate requested memory\n");
}
else
{
// Read Dynamically Allocated values

for (i=0; i<n;i++){
printf("Enter number %d :", i+1);
scanf("%d",&dynamic_var[i]);
}
}
// Printing Dynamically Allocated values
for (i=0; i<n;i++){
printf("Number %d = %d \n", i+1, dynamic_var[i]);

}

free(dynamic_var);

return 0;
}

এখানে আমরা dynamic_var নামক একটা ইন্টিজার পয়েন্টার ভ্যারিয়েবল নিয়েছি। আমরা dynamic_var এ কয়েকটি নাম্বার স্টোর করতে চাই, তা ইনপুট নিয়েছি n নামক ভ্যারিয়েবল দিয়ে। এরপর এটার সাইজ ডাইনামিক্যালি এলোকেট করেছি, n * sizeof(int) দিয়ে।
এরপরের কাজ সহজ। আমরা ফর লুপ চালিয়ে নাম্বার গুলো ইনপুট নিয়েছি। এরপর সে গুলো আবার আউটপুট দিয়েছি।

calloc()

calloc() এবং malloc() এর সিনট্যাক্সে তেমন কোন পার্থক্য নেই। দুটাই একই ভাবেই ব্যবহার করা হয়। calloc() করে কি, প্রথমে ০ দিয়ে ইনিশিয়ালাইজ করে নেয়। পরে মেমরিতে পয়েন্টার রিটার্ন করে। একই উদাহরন calloc() দিয়ে লিখলেঃ


#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main()
{
char *dynamic_var;

dynamic_var =calloc( 200 , sizeof(char) );

if( dynamic_var== NULL )
{
printf("Couldn't able to allocate requested memory\n");
}
else
{
strcpy( dynamic_var,"Dynamically allocated string.");
}
printf("%s\n", dynamic_var );

free(dynamic_var);

return 0;
}

realloc()

calloc() এবং malloc() দিয়ে এলোকেট করা মেমরি যদি ইনসাফিশিয়েন্ট হয়, তাহলে realloc() দিয়ে প্রয়োজন অনুযায়ী আবার মেমরি এলোকেট করে নেওয়া যায়। উদারহণঃ


#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main()
{
char *dynamic_var;
//allocate
dynamic_var = malloc( 100 * sizeof(char) );

if( dynamic_var== NULL )
{
printf("Couldn't able to allocate requested memory\n");
}
else
{
strcpy( dynamic_var,"Dynamically allocated string.");
}
printf("%s\n", dynamic_var );

//reallocate
dynamic_var = realloc( dynamic_var, 200 * sizeof(char) );

if( dynamic_var== NULL )
{
printf("Couldn't able to allocate requested memory\n ");
}
else
{
strcat( dynamic_var,"With more reallocated content");
}
printf("%s\n", dynamic_var );

free(dynamic_var);

return 0;
}

উপরের প্রোগ্রামের প্রথম অংশ malloc() এর প্রথম উদারহণটির মতই। এর পরবর্তিতে আমাদের আরো কিছু যোগ করা দরকার, তাই আমরা realloc() ব্যবহার করে মেমরি বাড়িয়ে নিলাম।আরেকটা উদাহরণঃ


#include <stdio.h>
#include <stdlib.h>
int main(){
int *dynamic_var ,i,n1,n2;
printf("Enter size of array: ");
scanf("%d",&n1);

dynamic_var =(int*)malloc(n1*sizeof(int));

printf("Address of previously allocated memory: ");

for(i=0;i<n1;++i)
printf("%u\t",dynamic_var +i);

printf("\nEnter new size of array: ");
scanf("%d",&n2);

dynamic_var =realloc(dynamic_var ,n2);

for(i=0;i<n2;++i)
printf("%u\t",dynamic_var +i);
return 0;
}

এখানে প্রথমে জিজ্ঞেস করবে কত সাইজে অ্যারে দরকার। পরে তত সাইজের একটি অ্যারে তৈরি করবে। এবং ঐ অ্যারের এড্রেস গুলো প্রিন্ট করবে। আমরা চাইলে ঐ অ্যারেতে ইনপুট নিয়ে রাখতে পারি। প্রিন্ট করতে পারি।

এরপর আবার জিজ্ঞেস করবে নিউ অ্যারে সাইজ। এখন যদি আগের থেকে বড় কোন মান দিয়ে থাকি, তাহলে আগের থেকে বড় একটা অ্যারে আমাদের জন্য তৈরি করবে। ছোট ভ্যালু দিলে আগের অ্যারেটা ছোট করে দিবে।এবং অ্যারের এড্রেস গুলো প্রিন্ট করবে। যেমন প্রথম বার ৫ ইনপুট করে দেখুন। এরপরে ২ বা ৮ ইনপুট করে দেখতে পারেন।

 

Leave a Reply