Your question seems to be about how to understand the concept of memory allocation from a beginners point of view. Let me try to explain what is going on in a very simplified manner. As an example we can think of a C++ program that adds a lot of elements to a std::vector
.
When the program starts the C++ runtime will call the operating system to allocate some memory. This piece of memory is called the heap and it is used when dynamic memory is required by the C++ program. Initially the heap is mostly unused, but calls to new
and malloc
will carve out blocks of memory on the heap. Internally the heap uses some bookkeeping information to keep track of the used and free ares of the heap.
Exactly how std::vector
behaves internally depends on the implementation, but in general it will allocate a buffer for the elements of the vector on the heap. This buffer is big enough to accommodate all the elements in the vector, but most of the time it has some free space at the end. Here is a buffer that stores 5 elements and has space enough for 8 elements. The buffer is located at address 1000 on the heap.
1000: X X X X X _ _ _
The std::vector
keeps track of both the number of elements in the vector (5) and the size (8) and location (1000) of the buffer.
Here is the buffer after push_back
is called to add a new element to the vector:
1000: X X X X X X _ _
That can be done two more times until all space has been used in the buffer.
1000: X X X X X X X X
But what happens if push_back
is called once more? The vector has to increase the size of the buffer. The buffer is allocated on the heap and if the area right after the buffer is unused it may actually be possible to simply grow the buffer. However, most of the time the memory has been allocated to some other object. This is something the heap keeps track of. For the vector to be able to grow the buffer it has to allocate a completely new buffer with an increased size. Many implementations will simply double the size of the buffer. Here is the new buffer that now stores 9 elements and has room for 16 elements. The new buffer is allocated at address 2000 on the heap:
2000: X X X X X X X X X _ _ _ _ _ _ _
The contents of the old buffer is copied to the new buffer, and this operation can be costly if the buffer is big.
In case you wonder the heap may also grow while the program is running just as individual blocks allocated on the heap may grow. This will increase the memory consumption of the program. As more and more elements are added to the vector the heap will have to grow until the operating system refuses to increase the size of the heap. When that happens the program will fail with an out of memory condition.
To sum up:
- The operating system supplies memory for the heap that can grow in size until the limits of the operating system has been reached.
- The memory allocation routines in C++ can allocate and free blocks of fixed size on the heap.
- The
std::vector
will preallocate a buffer to allow the vector to grow, but if the vector grows beyond the size of the buffer it will allocate a new buffer and copy the entire contents of the vector to this new buffer.