The memory used by a program is typically divided into several areas. The exact organisation depends on the compiler, operating system and hardware, but commonly includes:
The stack – commonly used for function call information, including function parameters and local variables with automatic storage duration.
Global and static storage – used for global variables and variables with static storage duration.
The free store (heap) – used for dynamically allocated objects.
Registers – small, fast storage locations within the processor used to hold values and addresses while the program is running.
Code space – contains the machine instructions that make up the program.
The Free Store
The free store is an area of memory from which objects can be dynamically allocated while a program is running. Memory is allocated using the new operator and released using the delete operator.
When an object is allocated using new, the result is normally a pointer to the newly created object. The object remains allocated until it is explicitly released with delete or until the program terminates.
One advantage of dynamic allocation is that an object can remain available after the function in which it was created has returned. This allows the lifetime of an object to extend beyond the scope of the function that created it.
The disadvantage is that dynamically allocated memory must be managed correctly. If allocated memory is not released when it is no longer required, the program can develop a memory leak. Repeated memory leaks can cause a program to use increasing amounts of memory and may eventually cause performance problems or allocation failures.
Allocating Space with the New Keyword
Memory is dynamically allocated using the operator followed by the type of object to be created. The newnew operator allocates enough memory for the specified type and returns a pointer to the newly created object.
int *ptr = NULL;//creates a pointer ptr and assigns NULL
ptr = new int;// allocated space for an int on the heap and assign is address to pointer ptr
or
int *p = new int
Deallocating Space with the Delete Keyword
When an area of the free store is no longer required, it must be released back to the system. This is done by calling delete on the pointer. When an object allocated with new is no longer required, its memory can be released using the delete operator. The pointer used with delete must point to an object that was allocated using new.
If a pointer variable points to dynamically allocated memory and the pointer itself goes out of scope, the dynamically allocated memory is not automatically released. The memory remains allocated but can no longer be accessed through that pointer. This results in a memory leak.
#include <iostream>
int main()
{
int* pInt = new int; // allocate an int
*pInt = 7; // assign the value 7
std::cout << "*pInt: " << *pInt << '\n';
delete pInt; // release the allocated memory
pInt = nullptr; // avoid leaving a dangling pointer
return 0;
}
After delete pInt, the dynamically allocated int no longer exists and must not be accessed through pInt.
An alternative is to use std::nothrow with new. In this case, if the allocation fails, new returns nullptr instead of throwing an exception.
int *pInt = new(nothrow) int;
if (!pInt)
cout << "allocation of memory failed\n";
In modern C++, direct use of and new is generally avoided where possible. Standard library containers and smart pointers can manage dynamically allocated memory automatically and greatly reduce the risk of memory leaks.delete