Dynamic Memory Allocation - free store
C++ supports allocating memory to a variable at run time. This memory will be allocated in the heap . This process is called dynamic memory allocation.
Remember that all the local variables are stored in the stack and they are created and destroyed automatically. They are created at definition and destroyed when the block where they are defined exits.
Unlike this, the dynamic memory is created explicitly and should be destroyed explicitly. Failing to do so will cause memory leak.
In C we use malloc(), calloc() and realloc() for this dynamic allocation. And the memory thus allocated, is released using free().
In C++ dynamic memory allocation uses two operators, new and delete.
new operator
new operator allocates memory to a variable and returns a pointer to the memory block. new does not need number of bytes to be allocated unlike malloc. Instead it needs data type of pointee. Looking at the data type of pointee, compiler calculates number of bytes needed.
int *ptr = new int;
We are not specifying how many bytes must be allocated. But as ptr is an integer pointer, 8 bytes (if sizeof int is 8) are allocated and their starting address is returned.
This address is stored in ptr. Integer value pointed by ptr is not initialized.
To initialize the pointee we can use the modified form of new operator
int *ptr = new int(10);
Now we allocate memory for ptr and store 10 in the location pointed by ptr.
If new operator fails, it throws a bad_alloc exception. (exception is an error, which can be handles by C++ code).
new[] operator
The second version of new operator is new[]. This is used to allocate a block of memory, usually for an array of objects in contiguous memory locations.
For example, to allocate memory for a block of 10 integers, you can use
int *ptr2 = new int[10];/*allocate memory to 10 integers. */
The memory allocated using new[] should be released using delete[] operator.
Let us look at some examples with new and new[]
Here we are allocating memory to an integer pointer using new int and an array of floats using new float[5]. The second statement allocates memory for an array of 5 floating point numbers in contiguous memory locations.
delete operator
delete operator is used for releasing memory allocated using new operator.
delete ptr;
delete []ptr2;
delete with square brackets (delete []) is used to release memory allocated to an array values.(the memory which is allocated with new[]).
Any memory allocated using new operator should always be released using delete to avoid memory leaks.
Memory Leaks
Whenever you allocate memory using new operator, you should always release the memory using delete, after you have completed its usage. Because unlike other variables, dynamically created variables are not destroyed automatically when they go out of scope.
If memory is not released, at some point of time, the program will run out of memory. This is called memory leakage.
new and delete for objects
Memory can also be allocated to objects of classes and structures using new and delete operators.
new operator will allocate memory to the object, create the object and also call the constructor for the object.
delete will call the destructor and then destroy the object and release the memory.
Difference between malloc() and new:
You can still use malloc() function in C++. But malloc() needs the user to specify the number of bytes to be allocated and also, malloc() does not call constructor for objects.
Memory allocated using malloc() can be released using free(). But free() does not automatically call destructor for objects unlike delete operator.
int *ptr = malloc(sizeof(int));
*ptr = 10;
free(ptr);
Memory allocated using new should be released using delete. And memory allocated using malloc() should be released using free().
Exercises:
1) Define 3 integer pointers p1,p2,p3. Allocate memory to them. Now read 3 integers using these pointers and find the largest integer.
2) Allocate memory to a float array of n elements dynamically and read the array elements. Print them.