I need to make a custom memory manager, and I think I have grasped the concept, I need to allocate a block of memory up front and then hand out pointers to it as they are requested. I have this code which is just a quick first draft
but with this I couldnt use it just like new, for example I can't pass in variables to be used in it's constructor like MyClass pmc = new MyClass(10,50); so I can't instantiate my own classes with it.
I have to use it like this, for basic types
1 2 3 4 5 6 7 8 9 10 11 12 13
int* i = allocate<int>(1);
*i = 10;
int* j = allocate<int>(10);
for (int count=0; count<10; count++){
*(j+count) = count;
}
std::cout << "the address of i is: " << i << ", the value at this address is: " << *i << "\n";
for (int count=0; count<10; count++){
std::cout << "the address of j+" << count << " is: " << j+count << ", the value at address this address is: " << *(j+count) << "\n";
}
how can I expand this to allow me to instantiate my classes using the memory handled by my memory manager?
Look into using placement new. IIRC, you can use that to set an object's location in memory only and initialize it with the constructor explicitly yourself. http://en.wikipedia.org/wiki/Placement_new
Also your allocator currently permits only one type of objects to be allocated. The pos variable is offset in terms of T objects, and T could change from call to call, which would result in mismatch of different pos interpretations.
May I be so curious and ask, what is the use of the blocks list? And if you plan to implement deallocation?
Yes I plan to implement deallocation, and that is exactly what the list of blocks is for, it stores memory blocks currently being used and where they start and end in the huge block allocated at the start, so that i can free up memory and use it again.
I did ask, because I have been taught this the other way around. The free blocks are stored in a container, and the allocated blocks are not recorded. When someone asks for space, you pull suitable free block from the free blocks list. When someone releases previously allocated space, you add free block to the free blocks list.
If the goal is to have memory pool that delivers identical chunks, you can use list for the free blocks. With this implementation, allocation and deallocation will have constant complexity. If the purpose is to have universal allocator, then you should probably use multiset instead. In fact you may need "multi-indexing" with two keys. The first key is the block size. The set allows you to search for block with appropriate size in logarithmic time. The second key is the block location. This allows you to join adjacent free blocks that had been split during allocation. There are other strategies, but not all are portable.
Another issue is that you have to provide alignment. You can not simply return the starting address of the first free memory in which the object will fit. (Otherwise the allocator is strictly speaking not standard compliant, and consequently not completely portable.)