When I first started making the memory manager, I was aware that when I allocated and deallocated memory, there would be gaps in the memory from the deallocation. When memory was deallocated, I would move any allocated memory that had a higher memory address than the deallocated memory down to a lower memory address to remove any gaps that the deallocated memory left behind. As I moved allocated memory down to lower addresses, I realized that the pointer that was pointing at the relocated memory no longer pointed at the correct data. If the pointer tried to reference that data, then the wrong data would be referenced or perhaps the memory being referenced would be null.
Handles in this implementation are basically an index into an array of pointers to memory. I originally got the idea of using handles from Game Engine Architecture by Jason Gregory, in the Defragmentation and Relocation section. Gregory described three different ways to combat the relocation of pointers, carefully tracking the raw pointers, smart pointers, and handles.
Handles are much more flexible than raw pointers in regard to relocation. When memory is moved raw pointers would have to be manually adjusted but with handles when memory is moved, the indexes into the array stay the same but the pointer at said index will be moved to a lower memory address. When the handle tries to reference what it is pointing to it will go into the array and find the new or same memory address.
By Taylor Addington