0% found this document useful (0 votes)
10 views34 pages

Lecture9 - Dynamic Allocation

Uploaded by

kethanr.brn
Copyright
© © All Rights Reserved
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
Download as ppt, pdf, or txt
0% found this document useful (0 votes)
10 views34 pages

Lecture9 - Dynamic Allocation

Uploaded by

kethanr.brn
Copyright
© © All Rights Reserved
Available Formats
Download as PPT, PDF, TXT or read online on Scribd
Download as ppt, pdf, or txt
Download as ppt, pdf, or txt
You are on page 1/ 34

Dynamic Memory

Allocation
AUM SRI SAI RAM

1
Problem with Arrays
Sometimes
◦ Amount of data cannot be predicted beforehand
◦ Number of data items keeps changing during program execution
Example: Seach for an element in an array of N elements
One solution: find the maximum possible value of N and allocate
an array of N elements
◦ Wasteful of memory space, as N may be much smaller in some
executions
◦ Example: maximum value of N may be 10,000, but a particular
run may need to search only among 100 elements
◦ Using array of size 10,000 always wastes memory in most cases

2
Better Solution
Dynamic memory allocation
◦ Know how much memory is needed after the program is
run
◦ Example: ask the user to enter from keyboard
◦ Dynamically allocate only the amount of memory needed

C provides functions to dynamically allocate


memory
◦ malloc, calloc, realloc

3
Memory Allocation Functions
malloc
◦ Allocates requested number of bytes and returns a pointer
to the first byte of the allocated space
calloc
◦ Allocates space for an array of elements, initializes them to
zero and then returns a pointer to the memory.
free
◦ Frees previously allocated space.
realloc
◦ Modifies the size of previously allocated space.

4
Allocating a Block of Memory
A block of memory can be allocated using the function
malloc
◦ Reserves a block of memory of specified size and returns a pointer of type void
◦ The return pointer can be type-casted to any pointer type

General format:
type *p;
p = (type *) malloc (byte_size);

5
Example
p = (int *) malloc(100 * sizeof(int));
◦ A memory space equivalent to 100 times the size of an int bytes is reserved
◦ The address of the first byte of the allocated memory is assigned to the pointer
p of type int

400 bytes of space 6


Contd.
cptr = (char *) malloc (20);
Allocates 20 bytes of space for the pointer cptr of type char

sptr = (struct stud *) malloc(10*sizeof(struct stud));


Allocates space for a structure array of 10 elements. sptr points to a structure element
of type struct stud

Always use sizeof operator to find number of bytes for a data


type, as it can vary from machine to machine

7
Points to Note
malloc always allocates a block of contiguous bytes
◦ The allocation can fail if sufficient contiguous memory space is not available
◦ If it fails, malloc returns NULL

if ((p = (int *) malloc(100 * sizeof(int))) == NULL)


{
printf (“\n Memory cannot be allocated”);
exit();
}

8
Using the malloc’d Array
Once the memory is allocated, it can be used with pointers, or
with array notation
Example:
int *p, n, i;
scanf(“%d”, &n);
p = (int *) malloc (n * sizeof(int));
for (i=0; i<n; ++i)
scanf(“%d”, &p[i]);

The n integers allocated can be accessed as *p, *(p+1), *(p+2),…,


*(p+n-1) or just as p[0], p[1], p[2], …,p[n-1]

9
Example
int main() printf("Input heights for %d
{ students \n",N);
int i,N; for (i=0; i<N; i++)
float *height; scanf ("%f", &height[i]);
float sum=0,avg;
for(i=0;i<N;i++)
printf("Input no. of students\n"); sum += height[i];
scanf("%d", &N);
avg = sum / (float) N;
height = (float *)
malloc(N * sizeof(float)); printf("Average height = %f \n",
avg);
free (height);
return 0;
}

10
Releasing the Allocated Space: free
An allocated block can be returned to the system for
future use by using the free function
General syntax:
free (ptr);
where ptr is a pointer to a memory block which has
been previously created using malloc
Note that no size needs to be mentioned for the
allocated block, the system remembers it for each
pointer returned

11
Can we allocate only arrays?
malloc can be used to allocate memory for single variables also
◦ p = (int *) malloc (sizeof(int));
◦ Allocates space for a single int, which can be accessed as *p

Single variable allocations are just special case of array allocations


◦ Array with only one element

12
Array of pointers
#define N 20
#define M 10
int main()
{
char word[N], *w[M];
int i, n;
scanf("%d",&n);
for (i=0; i<n; ++i) {
scanf("%s", word);
w[i] = (char *) malloc ((strlen(word)+1)*sizeof(char));
strcpy (w[i], word) ;
}
for (i=0; i<n; i++) printf("w[%d] = %s \n",i,w[i]);
return 0;
}

13
Array of pointers
#define N 20 Output
#define M 10 4
int main() Tendulkar
{ Sourav
char word[N], *w[M]; Khan
int i, n; India
scanf("%d",&n); w[0] = Tendulkar
for (i=0; i<n; ++i) { w[1] = Sourav
scanf("%s", word); w[2] = Khan
w[i] = (char *) malloc ((strlen(word)+1)*sizeof(char)); w[3] = India
strcpy (w[i], word) ;
}
for (i=0; i<n; i++) printf("w[%d] = %s \n",i,w[i]);
return 0;
}

14
Howw it will look like malloc()

0 T e n d u l k a r \0
1 S o u r a v \0

2 K h a n \0

3 I n d i a \0

15
Pointers to Pointers
Pointers are also variables (storing addresses), so they
have a memory location, so they also have an address
Pointer to pointer – stores the address of a pointer
variable

int x = 10, *p, **q;


p = &x;
q = &p;
printf(“%d %d %d”, x, *p, *(*q));

will print 10 10 10 (since *q = p)


16
Allocating Pointer to Pointer
int **p;
p = (int **) malloc(3 * sizeof(int *));

p[0]
p int ** int *
p[1] int *
p[2] int *

17
2D array
#include <stdlib.h>

int main()
{
int **array;
array = (int**) malloc(nrows * sizeof(int *));

for(i = 0; i < nrows; i++)


{

array[i] = (int*)malloc(ncolumns * sizeof(int));

{
18
2D array
int main()
x 0
{ 1
**x=malloc(10*sizeof (int(*)));
2
*x; 3
*(x+1);

**(x+1); x[1][0]

*(*(x+1)+4) x[1][4] *(x[3]+7) ???


9
*((*x)+8) x[0][8]
}

19
Dynamic Allocation of 2-d Arrays
Recall that address of [i][j]-th element is found by
first finding the address of first element of i-th row,
then adding j to it
Now think of a 2-d array of dimension [M][N] as M 1-
d arrays, each with N elements, such that the starting
address of the M arrays are contiguous (so the
starting address of k-th row can be found by adding 1
to the starting address of (k-1)-th row)
This is done by allocating an array p of M pointers,
the pointer p[k] to store the starting address of the k-
th row

20
Contd.
Now, allocate the M arrays, each of N elements, with p[k] holding the
pointer for the k-th row array
Now p can be subscripted and used as a 2-d array
Address of p[i][j] = *(p+i) + j (note that *(p+i) is a pointer itself, and p is
a pointer to a pointer)

21
Dynamic Allocation of 2-d
Arrays
int **allocate (int h, int w)
{ void read_data (int **p, int h, int w)
int **p; Allocate array {
int i, j; of pointers int i, j;
for (i=0;i<h;i++)
p = (int **) malloc(h*sizeof (int *) ); for (j=0;j<w;j++)
for (i=0;i<h;i++) scanf ("%d", &p[i][j]);
p[i] = (int *) malloc(w * sizeof (int)); }
return(p);
} Allocate array of Elements accessed
integers for each like 2-D array elements.
row

22
Contd.
void print_data (int **p, int h, int w) int main()
{ {
int i, j; int **p;
for (i=0;i<h;i++) int M, N;
{ printf ("Give M and N \n");
for (j=0;j<w;j++) scanf ("%d%d", &M, &N);
printf ("%5d ", p[i][j]); p = allocate (M, N);
printf ("\n"); read_data (p, M, N);
} printf ("\nThe array read as \n");
} print_data (p, M, N);
return 0;
}

23
Contd.
void print_data (int **p, int h, int w) int main()
{ {
int i, j; int **p;
for (i=0;i<h;i++) int M, N;
{ printf ("Give M and N \n");
for (j=0;j<w;j++) scanf ("%d%d", &M, &N);
printf ("%5d ", p[i][j]); p = allocate (M, N);
printf ("\n"); read_data (p, M, N);
Give M and N
} 33
printf ("\nThe array read as \n");
} 123 print_data (p, M, N);
456 return 0;
789 }
The array read
as
1 2 3
4 5 6 24
Memory Layout in Dynamic Allocation
int **allocate (int h, int w)
int main() {
{ int **p;
int **p; int i, j;

int M, N;
p = (int **)malloc(h*sizeof (int *));
printf ("Give M and N \n");
for (i=0; i<h; i++)
scanf ("%d%d", &M, &N);
printf(“%10d”, &p[i]);
p = allocate (M, N); printf(“\n\n”);
for (i=0;i<M;i++) {
for (i=0;i<h;i++)
for (j=0;j<N;j++)
p[i] = (int *)malloc(w*sizeof(int));
printf ("%10d", &p[i][j]);
printf(“\n”); return(p);
} }
return 0;
}
25
allocate int and double array
int *intP;
Allocates 40 bytes
double *doubleP; sizeof(int) = 4
// Allocate space for 10 integers
intP = malloc(10 * sizeof(int));

// Allocate space for 10 doubles


Allocates 80 bytes
doubleP = malloc(10 * sizeof(double)); sizeof(double) = 8
realloc
realloc takes a pointer to allocated memory and reallocates the memory
to a larger size
◦ if it can make the old block bigger, great
◦ if not, it will get another, larger block, copy the old contents to the new
contents, free the old contents and return a pointer to the new

intP = malloc(sizeof(int));
intP = realloc(intP, 2*sizeof(intP));

intP may be different after a realloc!


int main () Step 1: Prompt the user to enter
{ the number of random numbers to
double *dblPtr; generate
int howMany, randNum;
printf("How many random numbers to generate:");
howMany=ProcessInput(stdin);
dblPtr = malloc(howMany * sizeof(double));
if (dblPtr == NULL)
{
printf("memory allocation error, exiting\n");
An example program
exit(1);
}

for (int i=0;i<howMany;i++)


{
randNum = random();
dblPtr[i]=(randNum%10000)/1000.0;
}

PrintArray(dblPtr,howMany);
int main ()
{ Step 2: create a dynamic array to
double *dblPtr; store the random numbers
int howMany, randNum;
printf("How many random numbers to generate:");
howMany=ProcessInput(stdin);
dblPtr = malloc(howMany * sizeof(double));
if (dblPtr == NULL) In this example we have
{ tested to be sure malloc
printf("memory allocation error, exiting\n");
exit(1); succeeded. If not, we are
} out of memory.
for (int i=0;i<howMany;i++)
{
randNum = random();
dblPtr[i]=(randNum%10000)/1000.0;
}

PrintArray(dblPtr,howMany);
int main ()
{ Step 3: generate the random
double *dblPtr; numbers and print them
int howMany, randNum;
printf("How many random numbers to generate:");
howMany=ProcessInput(stdin);
dblPtr = malloc(howMany * sizeof(double));
if (dblPtr == NULL)
{
printf("memory allocation error, exiting\n");
exit(1);
}

for (int i=0;i<howMany;i++)


{
randNum = random();
dblPtr[i]=(randNum%10000)/1000.0;
}

PrintArray(dblPtr,howMany);
dblPtr = realloc(dblPtr, 2*howMany); Step 4: double the size of the array using
realloc

for (int i=howMany; i<howMany*2; i++)


{
Step 5: generate more random
randNum = random();
dblPtr[i]=(randNum%10000)/1000.0; numbers and print them
}

howMany *= 2;

PrintArray(dblPtr, howMany);
free(dblPtr);
}
Passing pointers to function
Int main() void foo(int *a)
{ {
int x=5;
…………….. int m;
………….. m=*a;
5 1400
foo(&x); m=m+1;
x *a=m;
}
}
a 1400
&x=1400
*a

32
Call by value
Int main()
swap(int a, int b)
{
{
int x=10, y=5;
swap(x,y);
int temp;
temp=a;
a=b;
}
b=temp;

}
10 5
x y 10 5

a b

33
Call by Reference
Int main()
swap(int *a, int *b)
{
{
int x=10, y=5;
swap(&x,&y);
int temp;
Harman
temp=*a;
*a=*b;
*b=temp;
}
}
1400 10 5 1500 *b
x y
1400 1500
*a
a b
34

You might also like