DYNAMIC ALLOCATION OPERATORS
Computer's memory is an interesting thing. The way it works is so complex yet highly interesting.
Pointers provide necessary support for C++’s powerful dynamic
memory allocation system. As you know, dynamic allocation is the means by which
a program can obtain memory during runtime. The global and the local variables
are allocated memory during compile-time. However, you cannot add any global or
local variables during runtime.
What if, your program needs to use variable amount of memory space? In such case, you would need to allocate memory during runtime, as and when required. This can be done using the dynamic allocation operators.
DYNAMIC ALLOCATION
OPERATORS IN C++
C++ dynamic allocation routines obtain memory for allocation
from the free store (the pool of unallocated heap memory provided to the
program). C++ defines two unary operators new and delete that
perform the task of allocating and freeing (deallocating) memory during
runtime. In addition to these two operators, the C language functions malloc()
and calloc() are also defined in C++. Since all these operate on the
free memory, they are collectively called free store operators & functions.
We will focus on new and delete. However, here’s a brief about malloc()
and calloc() :
malloc()
It is a C based dynamic memory allocator used to allocate
memory from heap region during runtime. It is included in the header cstdlib.
The general syntax for malloc() is :
malloc() is generally used to create
dynamic arrays. It searches the memory for a suitable address where the array
of proper size can be created and returns the base address of the first memory
block. If it fails to allocate memory, it returns NULL. It is important
to note that malloc() only allocates memory but does not initialize it.
Therefore, all the allocated memory contains garbage value.
calloc()
It is also an inbuilt function included in the header file cstdlib. It
is used to allocate memory from heap region during runtime.
The general syntax is :
If calloc() fails to allocate memory, it returns a NULL. Also, unlike malloc(), it allocates and also initializes the memory blocks with legal default value depending on the data_type.
Learn all about malloc() and calloc() here. (link will be ready shortly.)
The ‘new’ operator
The operator new can be used to create objects of all
kinds, including user defined data types such as class or structures.
The general syntax for object creation using new :
where data_type is any valid C++ data type and the pointer_name is a pointer
variable of type data_type.
The operator new will allocate memory of size
equal to the size of given data_type and return a
pointer (of that specified data_type) pointing to the base address of the newly allocated
area.
For instance, the following code snippet
iptr = new int ;
This will allocate sufficient amount of memory from free storage to hold a value of specified data_type and store the starting address of the newly allocated memory in iptr. Since new is allocating the memory for int type, the receiving pointer must be of int type i.e. iptr must be an int pointer.
Declaration and allocation can be combined in one statement as
:
int * iptr = new int ;
Once a pointer points to a legal memory, we can access that memory using the “value at” operator * of pointers as shown below :
*iptr = 12 ;
The above assignment will assign the integer value 12 into the
newly allocated memory block.
This assignment can also be done at the time of allocation as
:
where value is the initial value to be stored in the newly
allocated memory. The value must also be of the specified data_type type .
Consider the following statements
The above given statement 1 will allocate sufficient memory
from free pool to hold a character, then store ‘a’ inside this newly allocated
memory, and make character pointer cptr point to this memory address.
Similarly, the statement 2 will allocate sufficient memory
from free pool to hold a floating point value, then store 17.33 inside that newly
allocated memory, and make float pointer fptr point to that memory address.
Creating Dynamic Array
The operator new can also allocate memory for user defined types like structures and classes as well as for derived data types like arrays. To allocate memory for a one-dimensional array, new may be used in the following form :
where size is an integer representing the number of elements in the
array.
For instance, to allocate memory for an array having 10
integer elements we need to use new as :
int * a = new int [10] ;
This will create an array of size 10 with a pointing to
the base address of the first element. Now all these array elements can be
accessed as
a[0] for the first element
a[1] for the second element
a[2] for the third element….and so on.
Before C++11 standards, no initializations were possible at
the time of creation of array but now we can also initialize the array with
some initial values as
This creates an array a with a[0] = 2, a[1] = 5 and so on.
The new operator does not initialize the newly created
memory unless explicitly forced by the programmer.
See the following code and its output :
Output :
1448160
The output is certainly a garbage value which is at present
stored in the newly created memory.
Now see this code :
Output :
0
As evident from above examples, to initialize memory allocated
through new, the program needs to force this initialization explicitly. Also,
arrays can be initialized with legal default values in the same way.
int * a= new int [5]();
This code creates an array of 5 elements and initializes the
elements with the default value of int type, i.e. 0.
In older versions of C++, it was not possible to create a
static array of variable size. For example,
int n;
cin>>n;
int a[n];
The above code would generate error as a variable has been
passed as the size of array. But the new standards allow such creations and so
the use of dynamic creation of arrays has now reduced.
An important note :
Since the program’s free store (heap) is not infinite, during
the course of program execution, it may become exhausted i.e. the program may run
out of heap memory and more memory may not be allocated further. To be on the
safer side in such a situation, whenever you allocate memory, you must check
the value returned by new operator to make sure it is not NULL or
zero before using the pointer. Using a NULL pointer will almost
certainly crash the system.
int *val = new int;
if(val)
*val=7;
else
cout<<”Out of
memory !!” ;
Even if, the initial value is given in the expression, initialization
is done only if the value returned by operator new is nonzero (or non-NULL).
If the value returned by new is 0 (NULL), the value of entire
expression becomes 0 (i.e. false).
The ‘delete’ operator
When an object, created through new, is no longer
needed, it must be destroyed so that the memory space occupied by it may be
released for reuse. This can be done with the help of delete operator,
the memory deallocation operator of C++.
The general form of delete is as shown below :
delete pointer_name ;
where pointer_name is the pointer that points to a data object created through new.
For deleting dynamic arrays created by new, we use the
following syntax :
delete [] pointer_name ;
Note : When we apply delete to a
pointer, it essentially deletes that memory which the pointer is pointing to.
It does not mean that the pointer itself is deleted. Any pointer is first a
static variable itself and it remains in memory for its entire scope.
If you like this article share with your friends.
Do not stop here. Read all articles related to C++ here.
If you have any doubts, queries or suggestions for the
website, please comment on this post.
If you want to contribute any article for the website, feel
free to share it on coding.nkcoder@gmail.com. We will
publish it on the website with your name.
Download the pdf form of this article here.
Related Topics :
Static & Dynamic Memory Allocations
Declaration and Initialization of pointers
Post a Comment