Creating a memory manager

Mar 4, 2011 at 7:21pm
Hello forum,

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
struct MemBlock{
	MemBlock(int start, int end) : start_(start), end_(end) {}

	int start_, end_;
};

std::list<MemBlock*> blocks;

int maxMemory = 1000;
void *memory = malloc(maxMemory);
int pos = 0;

template <typename T>
T* allocate(int size){
	if ( pos + size > maxMemory )
		throw "not enough memory available";
	else{
		blocks.push_back(new MemBlock(pos,pos+size));
		pos += size;
		T* toReturn = static_cast<T*>(memory);
		toReturn += pos;
		return toReturn;
	}
}


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?

Thanks =)
Mar 4, 2011 at 9:18pm
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
Mar 5, 2011 at 2:33am
+1 Zhuge

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?

Regards
Mar 5, 2011 at 10:39am
An STL compliant allocator has a specific interface.
http://www.codeproject.com/KB/cpp/allocator.aspx
Mar 5, 2011 at 1:06pm
@simeonz

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.

And big thanks to all of you for the advice
Mar 5, 2011 at 2:52pm
@MintBerryCrunch

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.)

Regards
Topic archived. No new replies allowed.