You can also allocate memory at runtime explicitly.
The simplest standard library function that allocates memory at runtime is
called malloc()
.
When you
use the malloc()
function, you specify the number of bytes of memory that
you want allocated as the argument.
The function returns the address of the first byte of memory that it allocated in response to your request.
A typical example of dynamic memory allocation might be this:
int *pNumber = (int*)malloc(100);
Here, you've requested 100 bytes of memory and assigned the address of this memory block to pNumber.
The following code allocates memory to hold 25 integers.
int *pNumber = (int*)malloc(25*sizeof(int));
(int*)
converts the address returned by the function to the type pointer to int.
#include <stdio.h>
#include <stdlib.h>
main() //w w w . j a v a2 s . co m
{
char *name;
name = (char *) malloc(80*sizeof(char));
if ( name != NULL ) {
printf("\nEnter your name: ");
gets(name);
printf("\nHi %s\n", name);
free(name); //free memory resources
} // end if
} //end main
The code above generates the following result.
The following code shows pattern to deal with memory allocation failure.
int *pNumber = (int*)malloc(25*sizeof(int));
if(!pNumber)
{
// Code to deal with memory allocation failure . . .
}
When allocating memory dynamically, you need to release the memory when it is no longer required.
To release the memory, you just write this statement:
free(pNumber); pNumber = NULL;
The free()
function has a formal parameter of type void*
,
you can pass a pointer of any type as the argument.
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
/*from www .j av a 2 s . c o m*/
int main(void)
{
unsigned long long *pPrimes = NULL; // Pointer to primes storage area
int total = 5; // Number of primes required
// Allocate sufficient memory to store the number of primes required
pPrimes = (unsigned long long*)malloc(total*sizeof(unsigned long long));
if(!pPrimes){
printf("Not enough memory.\n");
return 1;
}
free(pPrimes); // Release the heap memory . . .
pPrimes = NULL; // . . . and reset the pointer
return 0;
}
The code above generates the following result.
In this section, we will create a dynamic array using pointer.
In general, we can declare an array using [] with size. Now we can declare our array with dynamic size.
Basically, when we add a new value, we allocate memory and then attach it to array.
#include <stdio.h>
#include <stdlib.h>
/*from w w w . j ava2 s . c om*/
int main(int argc, const char* argv[]) {
// define dynamic array of pointer
int *numbers; // single array pointer
// a number of array
int N = 10;
// allocate memory
numbers = malloc( N * sizeof(int));
// set values
int i;
for(i=0;i<N;i++){
numbers[i] = i+3;
}
// display values
for(i=0;i<N;i++){
printf("%d ",numbers[i]);
}
printf("\n");
// free memory
free(numbers);
return 0;
}
The code above generates the following result.
Another sample, we also define dynamic array with multidimensional.
For instance, we create two dimensional dynamic array.
#include <stdio.h>
#include <stdlib.h>
//w w w . jav a 2 s . c om
int main(int argc, const char* argv[]) {
// define dynamic array of pointer
int **matrix; // two dimensional array pointer
// a number of array
int M = 3;
int N = 5;
// allocate memory
matrix = malloc( M * sizeof(int*));
// set values
int i,j;
for(i=0;i<M;i++){
matrix[i] = malloc( N * sizeof(int));
for(j=0;j<N;j++){
matrix[i][j] = i + j;
}
}
// display values
for(i=0;i<M;i++){
for(j=0;j<N;j++){
printf("%d ",matrix[i][j]);
}
printf("\n");
}
// free memory
free(matrix);
return 0;
}
The code above generates the following result.
The calloc()
function that is declared in the stdlib.h header.
And it offers a couple of advantages over malloc()
.
It allocates memory as a number of elements of a given size.
It initializes the memory that is allocated so that all bytes are zero.
The calloc() function requires two argument values: the number of data items and the size of each data item.
Both arguments are of type size_t
.
The address of the area allocated is returned as type void*.
Here's how you could use calloc()
to allocate memory for an array of 75 elements of type int:
int *pNumber = (int*) calloc(75, sizeof(int));
The return value will be NULL if it was not possible to allocate the memory requested.
You can let the compiler take care of supplying the cast:
int *pNumber = calloc(75, sizeof(int));
Example
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
/*from ww w . j ava 2s . co m*/
int main(void)
{
unsigned long long *pPrimes = NULL; // Pointer to primes storage area
int total = 5; // Number of primes required
// Allocate sufficient memory to store the number of primes required
pPrimes = calloc((size_t)total, sizeof(unsigned long long));
if (pPrimes == NULL) {
printf("Not enough memory. It's the end I'm afraid.\n");
return 1;
}
free(pPrimes); // Release the heap memory . . .
pPrimes = NULL; // . . . and reset the pointer
return 0;
}
The code above generates the following result.
The realloc() function enables you to reuse or extend memory that you previously allocated using malloc() or calloc() (or realloc()).
The realloc() function expects two argument values: a pointer containing an address that was previously returned by a call to malloc(), calloc(), or realloc() and the size in bytes of the new memory.
Individual memory segments acquired by malloc() can be treated much like array members; these memory segments can be referenced with indexes.
#include <stdio.h>
#include <stdlib.h>
main() /* ww w .j a v a 2 s .co m*/
{
int *numbers;
int x;
numbers = (int *) malloc(5 * sizeof(int));
if ( numbers == NULL )
return; // return if malloc is not successful
numbers[0] = 100;
numbers[1] = 200;
numbers[2] = 300;
numbers[3] = 400;
numbers[4] = 500;
printf("\nIndividual memory segments initialized to:\n");
for ( x = 0; x < 5; x++ )
printf("numbers[%d] = %d\n", x, numbers[x]);
}
The code above generates the following result.
The following code shows the expanding contiguous memory and realloc()'s outcome.
#include<stdio.h>
#include<stdlib.h>
main() /* w ww . ja va 2s. co m*/
{
int *number;
int *newNumber;
int x;
number = malloc(sizeof(int) * 5);
if ( number == NULL ) {
printf("\nOut of memory!\n");
return;
} // end if
printf("\nOriginal memory:\n");
for ( x = 0; x < 5; x++ ) {
number[x] = x * 100;
printf("number[%d] = %d\n", x, number[x]);
} // end for loop
newNumber = realloc(number, 10 * sizeof(int));
if ( newNumber == NULL ) {
printf("\nOut of memory!\n");
return;
}
else
number = newNumber;
//intialize new memory only
for ( x = 5; x < 10; x++ )
number[x] = x * 100;
printf("\nExpanded memory:\n");
for ( x = 0; x < 10; x++ )
printf("number[%d] = %d\n", x, number[x]);
//free memory
free(number);
}
The code above generates the following result.