1
Dynamic Memory
Allocation
2
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
3
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
4
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.
 We will only do malloc and free
5
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);
6
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
p
400 bytes of space
7
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
8
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();
}
9
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]
10
Example
printf("Input heights for %d
students n",N);
for (i=0; i<N; i++)
scanf ("%f", &height[i]);
for(i=0;i<N;i++)
sum += height[i];
avg = sum / (float) N;
printf("Average height = %f n",
avg);
free (height);
return 0;
}
int main()
{
int i,N;
float *height;
float sum=0,avg;
printf("Input no. of studentsn");
scanf("%d", &N);
height = (float *)
malloc(N * sizeof(float));
11
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
12
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
13
malloc( )-ing array of structures
typedef struct{
char name[20];
int roll;
float SGPA[8], CGPA;
} person;
void main()
{
person *student;
int i,j,n;
scanf("%d", &n);
student = (person *)malloc(n*sizeof(person));
for (i=0; i<n; i++) {
scanf("%s", student[i].name);
scanf("%d", &student[i].roll);
for(j=0;j<8;j++) scanf("%f", &student[i].SGPA[j]);
scanf("%f", &student[i].CGPA);
}
}
14
Static 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;
}
15
Static 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;
}
4
Tendulkar
Sourav
Khan
India
w[0] = Tendulkar
w[1] = Sourav
w[2] = Khan
w[3] = India
Output
16
w
0
1
2
3
9
How it will look like
T e n d u l k a r 0
S o u r a v 0
K h a n 0
I n d i a 0
malloc()
17
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)
18
Allocating Pointer to Pointer
int **p;
p = (int **) malloc(3 * sizeof(int *));
p
p[2]
p[1]
p[0]
int ** int *
int *
int *
2D array
19
#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));
}
{
2D array
20
Int main()
{
}
0
1
2
3
9
x
x
*x;
*(x+1);
**(x+1);
*(*(x+1)+4)
x[1][0]
x[1][4]
*((*x)+8) x[0][8]
*(x[3]+7) ???
21
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
22
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)
23
Dynamic Allocation of 2-d Arrays
int **allocate (int h, int w)
{
int **p;
int i, j;
p = (int **) malloc(h*sizeof (int *) );
for (i=0;i<h;i++)
p[i] = (int *) malloc(w * sizeof (int));
return(p);
}
Allocate array
of pointers
Allocate array of
integers for each
row
void read_data (int **p, int h, int w)
{
int i, j;
for (i=0;i<h;i++)
for (j=0;j<w;j++)
scanf ("%d", &p[i][j]);
}
Elements accessed
like 2-D array elements.
24
void print_data (int **p, int h, int w)
{
int i, j;
for (i=0;i<h;i++)
{
for (j=0;j<w;j++)
printf ("%5d ", p[i][j]);
printf ("n");
}
}
Contd.
int main()
{
int **p;
int M, N;
printf ("Give M and N n");
scanf ("%d%d", &M, &N);
p = allocate (M, N);
read_data (p, M, N);
printf ("nThe array read as n");
print_data (p, M, N);
return 0;
}
25
void print_data (int **p, int h, int w)
{
int i, j;
for (i=0;i<h;i++)
{
for (j=0;j<w;j++)
printf ("%5d ", p[i][j]);
printf ("n");
}
}
Contd.
int main()
{
int **p;
int M, N;
printf ("Give M and N n");
scanf ("%d%d", &M, &N);
p = allocate (M, N);
read_data (p, M, N);
printf ("nThe array read as n");
print_data (p, M, N);
return 0;
}
Give M and N
3 3
1 2 3
4 5 6
7 8 9
The array read
as
1 2 3
4 5 6
26
Memory Layout in Dynamic Allocation
int **allocate (int h, int w)
{
int **p;
int i, j;
p = (int **)malloc(h*sizeof (int *));
for (i=0; i<h; i++)
printf(“%10d”, &p[i]);
printf(“nn”);
for (i=0;i<h;i++)
p[i] = (int *)malloc(w*sizeof(int));
return(p);
}
int main()
{
int **p;
int M, N;
printf ("Give M and N n");
scanf ("%d%d", &M, &N);
p = allocate (M, N);
for (i=0;i<M;i++) {
for (j=0;j<N;j++)
printf ("%10d", &p[i][j]);
printf(“n”);
}
return 0;
}
27
Output
3 3
31535120 31535128 31535136
31535152 31535156 31535160
31535184 31535188 31535192
31535216 31535220 31535224
Starting address of each
row, contiguous (pointers
are 8 bytes long)
Elements in each
row are contiguous
Passing pointers to function
28
Int main()
{
int x=5;
……………..
…………..
foo(&x);
}
void foo(int *a)
{
int m;
m=*a;
m=m+1;
*a=m;
}
x
5
&x=1400
1400
a
*a
1400
Call by value
29
Int main()
{
int x=10, y=5;
swap(x,y);
}
swap(int a, int b)
{
int temp;
temp=a;
a=b;
b=temp;
}
x y
10 5
a b
10 5
Call by Reference
30
Int main()
{
int x=10, y=5;
swap(&x,&y);
}
swap(int *a, int *b)
{
int temp;
temp=*a;
*a=*b;
*b=temp;
}
x y
10 5
1400 1500
a b
1400 1500
*a
*b

dynamic_v1-memory-management-in-c-cpp.ppt

  • 1.
  • 2.
    2 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
  • 3.
    3 Better Solution  Dynamicmemory 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
  • 4.
    4 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.  We will only do malloc and free
  • 5.
    5 Allocating a Blockof 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);
  • 6.
    6 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 p 400 bytes of space
  • 7.
    7 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
  • 8.
    8 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(); }
  • 9.
    9 Using the malloc’dArray  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]
  • 10.
    10 Example printf("Input heights for%d students n",N); for (i=0; i<N; i++) scanf ("%f", &height[i]); for(i=0;i<N;i++) sum += height[i]; avg = sum / (float) N; printf("Average height = %f n", avg); free (height); return 0; } int main() { int i,N; float *height; float sum=0,avg; printf("Input no. of studentsn"); scanf("%d", &N); height = (float *) malloc(N * sizeof(float));
  • 11.
    11 Releasing the AllocatedSpace: 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
  • 12.
    12 Can we allocateonly 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
  • 13.
    13 malloc( )-ing arrayof structures typedef struct{ char name[20]; int roll; float SGPA[8], CGPA; } person; void main() { person *student; int i,j,n; scanf("%d", &n); student = (person *)malloc(n*sizeof(person)); for (i=0; i<n; i++) { scanf("%s", student[i].name); scanf("%d", &student[i].roll); for(j=0;j<8;j++) scanf("%f", &student[i].SGPA[j]); scanf("%f", &student[i].CGPA); } }
  • 14.
    14 Static array ofpointers #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; }
  • 15.
    15 Static array ofpointers #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; } 4 Tendulkar Sourav Khan India w[0] = Tendulkar w[1] = Sourav w[2] = Khan w[3] = India Output
  • 16.
    16 w 0 1 2 3 9 How it willlook like T e n d u l k a r 0 S o u r a v 0 K h a n 0 I n d i a 0 malloc()
  • 17.
    17 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)
  • 18.
    18 Allocating Pointer toPointer int **p; p = (int **) malloc(3 * sizeof(int *)); p p[2] p[1] p[0] int ** int * int * int *
  • 19.
    2D array 19 #include <stdlib.h> intmain() { int **array; array = (int**) malloc(nrows * sizeof(int *)); for(i = 0; i < nrows; i++) { array[i] = (int*)malloc(ncolumns * sizeof(int)); } {
  • 20.
  • 21.
    21 Dynamic Allocation of2-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
  • 22.
    22 Contd.  Now, allocatethe 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)
  • 23.
    23 Dynamic Allocation of2-d Arrays int **allocate (int h, int w) { int **p; int i, j; p = (int **) malloc(h*sizeof (int *) ); for (i=0;i<h;i++) p[i] = (int *) malloc(w * sizeof (int)); return(p); } Allocate array of pointers Allocate array of integers for each row void read_data (int **p, int h, int w) { int i, j; for (i=0;i<h;i++) for (j=0;j<w;j++) scanf ("%d", &p[i][j]); } Elements accessed like 2-D array elements.
  • 24.
    24 void print_data (int**p, int h, int w) { int i, j; for (i=0;i<h;i++) { for (j=0;j<w;j++) printf ("%5d ", p[i][j]); printf ("n"); } } Contd. int main() { int **p; int M, N; printf ("Give M and N n"); scanf ("%d%d", &M, &N); p = allocate (M, N); read_data (p, M, N); printf ("nThe array read as n"); print_data (p, M, N); return 0; }
  • 25.
    25 void print_data (int**p, int h, int w) { int i, j; for (i=0;i<h;i++) { for (j=0;j<w;j++) printf ("%5d ", p[i][j]); printf ("n"); } } Contd. int main() { int **p; int M, N; printf ("Give M and N n"); scanf ("%d%d", &M, &N); p = allocate (M, N); read_data (p, M, N); printf ("nThe array read as n"); print_data (p, M, N); return 0; } Give M and N 3 3 1 2 3 4 5 6 7 8 9 The array read as 1 2 3 4 5 6
  • 26.
    26 Memory Layout inDynamic Allocation int **allocate (int h, int w) { int **p; int i, j; p = (int **)malloc(h*sizeof (int *)); for (i=0; i<h; i++) printf(“%10d”, &p[i]); printf(“nn”); for (i=0;i<h;i++) p[i] = (int *)malloc(w*sizeof(int)); return(p); } int main() { int **p; int M, N; printf ("Give M and N n"); scanf ("%d%d", &M, &N); p = allocate (M, N); for (i=0;i<M;i++) { for (j=0;j<N;j++) printf ("%10d", &p[i][j]); printf(“n”); } return 0; }
  • 27.
    27 Output 3 3 31535120 3153512831535136 31535152 31535156 31535160 31535184 31535188 31535192 31535216 31535220 31535224 Starting address of each row, contiguous (pointers are 8 bytes long) Elements in each row are contiguous
  • 28.
    Passing pointers tofunction 28 Int main() { int x=5; …………….. ………….. foo(&x); } void foo(int *a) { int m; m=*a; m=m+1; *a=m; } x 5 &x=1400 1400 a *a 1400
  • 29.
    Call by value 29 Intmain() { int x=10, y=5; swap(x,y); } swap(int a, int b) { int temp; temp=a; a=b; b=temp; } x y 10 5 a b 10 5
  • 30.
    Call by Reference 30 Intmain() { int x=10, y=5; swap(&x,&y); } swap(int *a, int *b) { int temp; temp=*a; *a=*b; *b=temp; } x y 10 5 1400 1500 a b 1400 1500 *a *b