• facebook
  • whatsapp
  • telegram

 Dynamic Memory Allocation

సీ లాంగ్వేజీ లో ఉన్న arrays ( int a[10]) ఉపయోగించి రాసిన ప్రోగ్రాంల్లో flexibility ఉండదు. flexibility కావాలంటే memory నిరుపయోగం అవుతుంది. ఈ రెండు సమస్యలను అధిగమించడానికి మనం dynamic arrays వాడతాం. అంటే, ప్రోగ్రాం రన్ అవుతున్నపుడు ఎన్ని elements ఉండే array కావాలో అంతదే create చేయవచ్చు.ఈ విధంగా create చేసిన arrays memory ఎప్పుడైనా de-allocate చెయ్యవచ్చు. అదే లాంగ్వేజి లో ఉన్న arrays memory ని మనం de-allocate చెయ్యలేం.


memory management కోసం వాడే Functions వివరాలు.
1. void * malloc(int n)
ఈ function ఒక integer (n)ను argument గా తీసుకొని అన్ని bytes ఉండే memoryని allocate చేసి దాని starting address (generic address) ని రిటర్న్ చేస్తుంది. memory allocate చేయలేకపొతే ఇది null రిటర్న్ చేస్తుంది.
2. free(address)
ఈ function లోకి ఒక address పంపిస్తే ఆ address నుంచి మనకు allocate చేసి ఉన్న memory de-allocate అవుతుంది.

1-D Dynamic Array Creation
     int *a, N, i,j;
     printf(“Enter required number of elements of array to be created \n”);
     scanf(“%d”, &N);

     /* allocating memory for the array */
     a=(int *) malloc(N* sizeof(int));

పైన N* sizeof(int) అనేది మనకు కావాల్సిన arrayకు కావల్సిన memory(bytes లో). Function malloc అన్ని bytes ఉండే memory allocate చేసి దాని addressని void *(generic address)గా ఇస్తుంది. దానిని integer address లోనికి int * వాడి typecast చేసి integer pointer a కు ఇస్తున్నాం. ఈ memory ని మనం ఎలా కావలంటే అలా చూడవచ్చు. ఒక float array గా చూడాలంటే వచ్చిన address ను float * లోనికి typecast చెయ్యాలి. ఒక double array లాగా చూడాలంటే వచ్చిన address ను double * లోకి typecast చెయ్యాలి. ఇక్కడ, a అనే దానిని first element కి సంబంధించిన address అని అనుకోవచ్చు. అలాగే, a+1, a+2, …అనేవి పక్క elements addressలు అవుతాయి. మన కంప్యూటరులో integerకు 2 bytes అని, మొదటి element address 100 అని అనుకుంటే, పక్కపక్క elements addressలను ఇలా చూపించవచ్చు.


గమనిక: మన కంప్యూటరులో float variable కు 4 bytes allocate అయితే, a ఒక float pointer అయితే, a విలువ x అయితే a+6 విలువ x+6*4 అవుతుంది.
double variableకు 8 bytes allocate అయితే, a ఒక double pointer అయితే, a విలువ x అయితే a+6 విలువ x+6*8 అవుతుంది.
char variableకు 1 byte allocate అయితే, a ఒక character pointer అయితే, a విలువ x అయితే a+6 విలువ x+6 అవుతుంది. ఇలా pointers టైప్ పని చేస్తుంది. అలాగే, a కనుక float pointer అయితే, a++ (లేక ++a) అయిన తర్వాత దాని విలువ 4 పెరిగి ఉంటుంది. అలాగే, ఇక్కడ 'a' float pointer అయితే, a-- (లేక --a) అయిన తర్వాత దాని విలువ 4 తగ్గి ఉంటుంది. ఇవి వేరే టైప్ pointers variables కూడా వర్తిస్తాయి.

Reading the data into array
పైన చెప్పిన విధంగా, a+i అనేది మనం create చేసిన array లోని ith element address. కాబట్టి దానిని వాడి scanf ద్వారా array లోపలికి డేటా ఇలా రీడ్ చేస్తాం.
     for(i=0;i

Printing the data of the array
అలాగే, a+i అనేది మనం create చేసిన array లోని ith element address అయితే *( a+i) అనేది దాని విలువను indicate చేస్తుంది. ఇక్కడ కూడా a[i] వాడవచ్చు. ఈ కింద ఇచ్చినది, array లో ఉన్న విలువల ను ప్రింట్ చేస్తుంది.

     for(i=0;i

Example 8: పైన చెప్పినవన్నీ కలిపి ఉన్న ప్రోగ్రాం చూద్దాం.
#include
#include

int main()
{
     int *a,n,i;
     printf("Enter the size of the array:");
     scanf("%d",&n);
     a=(int*)malloc(n*sizeof(int)); /* Allocating memory */
     printf(“Enter elements into array\n”);
     for(i=0;i      printf(“Array elements are \n”);

     for(i=0;i      free(a); /* to de-allocate memory*/
     return 0;
}
పైన ఇచ్చిన ప్రోగ్రాంను రన్ చేసినప్పుడు కంప్యూటరు మీద ఈ విధంగా ఉంటుంది.

Example 9: ఈ ప్రోగ్రాం pointers మీద increment, decrement, relational operators ఉపయోగించటాన్ని చూపిస్తుంది. టోటల్ మీద, మనం create చేసి రీడ్ చేసిన array విలువ reverse అయిన తర్వాత ప్రింట్ చేస్తుంది.
#include
#include
void swap(int*a,int*b)
{
     int T,
     T=*a;
     *a=*b;
     *b=T;

}
int main()
{
     int *a,n,i,*p,*q;
     printf("Enter the size of the array:\n”);
     scanf("%d",&n);
     a=(int*)malloc(n*sizeof(int));
     printf(“Enter elements into array\n”);

     for(i=0;i      p=a;
     q=a+n-1;

     while(p

     /* Initially, q are pointers to first and last elements respectively (say for example 100, 114 respectively). In next loop they are pointers to second and last but one elements. Each time their addresses are sent to SWAP function which exchanges the values at those addresses. Thus entire array values get reversely stored. */
     printf(“Array elements are \n”);
     for(i=0;i      return 0;
}


పైన ఇచ్చిన ప్రోగ్రాంను రన్ చేసినప్పుడు కంప్యూటరు మీద ఈ విధంగా ఉంటుంది.

15.04.1 Dangling Memory

Memory మన కోసం allocate అయి మనం వాడుకోలేని mmemoryని Dangling memory అని అంటారు. ఇది సాధారణంగా జరిగే తప్పే. ఒక functionలో dynamic array create చేసి, దాని addressను రిటర్న్ చేయకుండా బయటకు వస్తే, అది dangling memory అవుతుంది. ఆ functionలో create చేసిన dynamic array ను ఏ function అయినా వాడుకోవాలంటే దాని address తెలిస్తేనే వీలవుతుంది. అంటే ఆ function కనుక address రిటర్న్ చేస్తే dangling memory లేకుండా చేసినట్లు అవుతుంది. ఈ కింది ప్రొగ్రాంలో, return p; లేకపోతే dangling memory సమస్య ఉన్నట్లు.

Example 10:

#include
#include
char* RS()
{
     char x[80], *p;
     printf(“Enter a string\n”);
     scanf(“%s”, x);
     p=(char *) malloc(strlen(x)+1);
     strcpy(p,x);
     return p;
}

int main()
{
      char *T;
     T=RS();
      printf(“ Given string = %s\n”, T); /* Given string will be printed now*/
     return 0;
}

పైన ఇచ్చిన ప్రోగ్రాంను రన్ చేసినప్పుడు కంప్యూటరు మీద ఈ విధంగా ఉంటుంది.

15.04.2 Dangling Pointer
ఏదైనా pointer, మన account లో లేని memory ని point చేస్తూంటే దానిని dangling pointer అని అంటారు. అది point చేస్తున్న memory ని దీని ద్వారా access చేస్తే మనకు run-time error వస్తుంది. ఇది కూడా మన తప్పు చేయడం వల్ల వస్తుంది. pointer variableను free() function లోకి పంపి memoryని free చేసినా, pointer variable విలువ అదే ఉంటుంది. దీన్ని సరిదిద్దాలంటే, free function call అయిన వెంటనే, pointer variable కు సున్నా ఇవ్వాలి.
Example 11: ఈ ప్రొగ్రాంలో ఒక function లోకి 1-D integer array పంపి elements average, maximum, minimum లను రిటర్న్ చేస్తుంది. దీనికి గానూ ఒక dynamic arrayను function లో create చేసి మనం రిటర్న్ చేయాల్సిన మూడు విలువలను అందులో పెట్టి dynamic array కి సంబంధించిన starting address రిటర్న్ చేస్తున్నాం.

int * stat4(int a[], int n)
{
     int I,s,max,min,*p;
     for(I=1,s=a[0],max=a[0],min=a[0];I      {
     s+=a[I];
     if(max      if(min>a[I])min=a[I];
     }
     p=(int* ) malloc(3*sizeof(int));

     p[0]=s/n; *(p+1)=max; p[2]=min;
     /* Three values are stored in dynamic array p */
     return (p); /* address of the dynamic array is returned*/
}
int main()
{
     int N, a[10],I,*RES;
     printf(“Enter a Number\n”);
     scanf(“%d”, &N);
     /* reading elements into array */
     for(I=0;I      /* calling the function*/
     RES=stat4(a, N);
     /* RES becomes pointer to the array created in function which is having maximum, minimum and average */
     printf(“Average=%d\n Maximum=%d\n Minimum=%d\n”, RES[0],RES[1],RES[2]);
     return 0;
}

పైన ఇచ్చిన ప్రోగ్రాంను రన్ చేసినప్పుడు కంప్యూటరు మీద ఈ విధంగా ఉంటుంది.

15.04.3 Creating 2D Arrays Flexibly (Array of pointers approach)

మనం1-D arraysను ఎలా flexibleగా create చెయ్యాలో నేర్చుకున్నాం. ఇప్పుడు 2-D arrays ను ఎలా create చెయ్యాలో నేర్చుకుందాం. ముందుగా మనకు కావలసిన టైప్ లో ఉన్న ఒక pointer array ( ఉదాహరణ: int *a[10] )ను తీసుకుంటాం. ఆ తర్వాత మనకు కావల్సిన 2-D array కి సంబంధించిన rows (1-D arrays ) ను malloc ద్వారా create చేస్తూ, వచ్చిన ప్రతీ 1-D array address (starting element addresses)ను pointer array లో స్టోర్ చేస్తాం. ఈ address లు ద్వారా మనం create చేసిన 2-D arrayలోని ఏ element అయినా access చేయవచ్చు.ఈ కింద ఇచ్చిన బొమ్మను, example programను చూడండి.

Example 12: ఈ ప్రోగ్రాంఒక 2-D arrayను array of pointers ద్వారా create చేస్తుంది.
#include
int main()
{
     int *a[10],nr,nc,i,j; /* pointer array a is declared*/

     printf("Enter no of rows and no of columns: \n”);
     scanf("%d%d",&nr,&nc);

     /* Memory for each row is created and their starting addresses
are stored in the pointer array a */

     for(i=0;i      a[i]=(int*)malloc(nc*sizeof(int));

     printf("Enter the values :");
     for(i=0;i      for(j=0;j      scanf("%d", a[i]+j );

     printf(“Array Values are\n”);
     for(i=0;i       {
     for(j=0;j      printf("\n");
     }
     return 0;
}
పైన ఇచ్చిన ప్రోగ్రాంను రన్ చేసినప్పుడు కంప్యూటరు మీద ఈ విధంగా ఉంటుంది.

15.04.4 Creating 2D Arrays Flexibly (Pointers to pointers approach)
పైన వాడిన అప్రొచ్ లో, మనం create చేయగలిగిన 2-D arrays లో rowలు మనం వాడుతున్న pointer array size కంటే ఎక్కువగా చేయలేం. అందుకని, ఈ pointer array కు కావల్సిన మెమొరీ కూడా dynamic గా allocate చేస్తే సరిపోతుంది. దీనిని pointer to pointer approach అని అంటారు. ఇక్కడ ముందుగా, ఒక pointer to pointer (int **p)ను declare చేసి, దానికి dynamic గా create చేసిన pointer array కి సంబంధించిన address ను assign చేస్తాం. ఆ తర్వాత పై example లానే జరుగుతుంది.

ఈ కింద ఇచ్చిన బొమ్మ, example program దీనిని చూపిస్తుంది.


Example 13: ఈ ప్రోగ్రాంఒక 2-D arrayను pointer to pointer approach ద్వారా create చేస్తుంది.
#include
int main()
{
     int **p,nr,nc,i,j;

     printf("Enter no of rows and no of columns: \n");
     scanf("%d%d",&nr,&nc);

     /* First a pointer array is created to store addresses of each row */

     p=(int **) malloc(nr*sizeof(int *));

     /* Memory for each row is created and their starting addresses
are stored in pointer array p */

     for(i=0;i      p[i]=(int*)malloc(nc*sizeof(int));

     printf("Enter the values :");
     for(i=0;i      for(j=0;j      scanf("%d",*(p+i)+j);
     printf(" array values are \n2-D array content is :");
     for(i=0;i      {
     for(j=0;j      printf("\n");
     }
     return 0;
}

పైన ఇచ్చిన ప్రోగ్రాంను రన్ చేసినప్పుడు కంప్యూటరు మీద ఈ విధంగా ఉంటుంది.

 

 

 

NB Venkateswarlu
M.Tech(IIT-Kanpur)
Ph.D (BITS),PDF(UK),
Sr.Prof., CSE, AITAM, Tekkali

Posted Date : 04-02-2021 .