Dynamic Memory Allocation

Why Dynamic Memory Allocation is Required ?

The exact size of array is unknown until the compile time,i.e., time when a compiler compiles code written in a programming language into a executable form. The size of array you have declared initially can be sometimes insufficient and sometimes more than required. Dynamic memory allocation allows a program to obtain more memory space, while running or to release space when no space is required.

Although, C language inherently does not has any technique to allocated memory dynamically, there are 4 library functions under "stdlib.h" for dynamic memory allocation.

malloc()

If the allocation succeeds, a void pointer to the allocated memory is returned or NULL is returned if there is insufficient memory available.To return a pointer to a type other than void, use a type cast on the return value.

If size is 0, malloc allocates a zero-length item in the heap and returns a valid pointer to that item. Always check the return from malloc, even if the amount of memory requested is small.

If it is unable to find the requested amount of memory, malloc() function returns NULL. So you should really check the result for errors:

Syntax : ptr=(cast-type*)malloc(byte-size)
eg.      ptr = (int *)malloc(100 * sizeof (int)); //The contents of allocated memory are not changed. i.e., the memory contains unpredictable or garbage values which creates a risk.
This statement will allocate either 200 or 400 according to size of int 2 or 4 bytes respectively and the pointer points to the address of first byte of memory.

#include <stdio.h>
int main()
{
        int *p;
        p = (int *) malloc(sizeof(int)*2147483647);
        if (p==NULL)
                printf("Out of memory\n");
        return 0;
}

Output :
Out of memory

calloc()

allocates a contiguous block of memory large enough to hold nelements of size bytes each. The allocated region is initialized to zero.

Initialization : malloc() does not initialize the memory allocated, while calloc() initializes the allocated memory to ZERO.

Syntax : ptr=(cast-type*)calloc(n,element-size);
This statement will allocate contiguous space in memory for an array of n elements

eg. int *ptr = calloc(10,sizeof (int)); // The allocated region is initialized to zero.
This statement allocates contiguous space in memory for an array of 25 elements each of size of float, i.e, 4 bytes.


calloc(m, n) is essentially equivalent to:
p = malloc(m * n);
memset(p, 0, m * n);
  // setting value to zero

Why does malloc() return a void*?
It’s because malloc() has no idea which type of object we want to put in that memory.


Some Hands On :

#include <stdio.h>
void allocateArray(int *arr){
        arr=(int*)malloc(100);
        arr[0]=137;
        printf("arr[0] in allocateArray :%d\n", arr[0]);
}

int main()
{
        int *arr;
        allocateArray(arr);
        printf("arr[0] in main :%d", arr[0]);
        getchar();
        return 0;
}


What will be output :

When calling allocateArray in main, you are passing array by value, so it is completely unchanged by the call to allocateArray . the “array” inside allocateArray is a copy of the original array from main(), and it is this copy that is assigned the result of the malloc call and  not the original array in main().

OUTPUT:
arr[0] in allocateArray :137
arr[0] in main :0

free()
Dynamically allocated memory with either calloc() or malloc() does not get return on its own. The programmer must use free() explicitly to release space.

syntax : free(ptr);
This statement cause the space in memory pointer by ptr to be deallocated.

realloc()
If the previously allocated memory is insufficient or more than sufficient. Then, you can change memory size previously allocated using realloc().

Syntaxptr=realloc(ptr,newsize);
Here, ptr is reallocated with size of newsize.



New memory allocation will be contiguous, explained in below program.

 
#include <stdio.h>
#include <stdlib.h>
int main()
{
        int *ptr,i,n1,n2;
        printf("Enter size of array: ");
        scanf("%d",&n1);
        ptr=(int*)malloc(n1*sizeof(int));
        printf("Address of previously allocated memory: ");
        for(i=0; i<n1; ++i)
                printf("%u\t",ptr+i);
        printf("\nEnter new size of array: ");
        scanf("%d",&n2);
        ptr=realloc(ptr,n2);
        printf("Address after realloc is :");
        for(i=0; i<n2; ++i)
                printf("%u\t",ptr+i);
        return 0;
}


OUTPUT :
Enter size of array: 1
Address of previously allocated memory: 134520840
Enter new size of array: 2
Address after realloc is :134520840     134520844

No comments:

Post a Comment