Skip to main content
GameDev.net gamedev.net
🔒 Locked

Memory Manager

Started by Hippokrates Jun 1, 2003 at 12:19 PM 4 replies 1.2k views
Original Post
Hippokrates
Hippokrates
How can I write a memory manager that is able to allocate a block of memory when my program starts and then gives me some memory whenever I need one. I would like to do something like this:
//Start

MemoryManager.Init(1024); //1 KB memory (just an example...)


//Runtime

CSuperman * p = MemoryManager.Request(...); //I need the memory now


//End

MemoryManager.Delete(p);
Is this possible? If yes, how? [edited by - Hippokrates on June 1, 2003 1:21:19 PM]
Im Anfang war die Tat...Faust
Oluseyi
Oluseyi
An extremely rudimentary memory manager class:
class MemoryManager
{
private:
typedef std::map< char *, char * > MemoryMap;
unsigned long totalMemory;
unsigned long blockSize;
unsigned long freeBlocks;
char * freeMemPtr;
MemoryMap allocatedMem, releasedMem;
 
public:
// skip the scaffolding functions like constructor, destructor

 
char * Allocate( unsigned long blocks )
{
if( blocks < freeBlocks )
{
freeBlocks -= blocks;
char * allocate = freeMemPtr;
freeMemPtr += blocks * blockSize * sizeof( char );
allocatedMem.insert( std::make_pair(allocate, freeMemPtr) );
}
else
throw std::runtime_error( "Out of memory!" );
return allocate;
}
 
void Release( char *& memoryPtr )
{
char * blockEnd;
MemoryMap::iterator it = allocatedMem.find( memoryPtr );
if( it != allocatedMem.end() )
{
blockEnd = it->second;
releasedMem.insert( std::make_pair(memoryPtr, blockEnd) );
allocatedMem.erase( it );
}
else
throw std::runtime_error( "Indicated memory is not in managed range!" );
}
 
void Compact();
 
unsigned long SetBlockSize( unsigned long size )
{
// require new block size to be either multiple or factor

// of old block size

if( size < blockSize && (blockSize % size == 0) )
{
// size is a factor. scale freeBlocks by multiplicand

freeBlocks *= blockSize / size;
}
else if( blockSize < size && (size % blockSize == 0) )
{
// size is a multiple.

freeBlocks *= size / blockSize;
}
else
// throw up

throw std::runtime_error( "Invalid block size!" );
unsigned long oldSize = blockSize;
blockSize = size;
return oldSize;
}
};
The Compact method is left as an exercise to the reader. Its function is to eliminate interspersed free regions of memory that occur as memory is allocated and released. Another modification to be made is to first check releasedMem for a suitably sized block before allocating off the unused memory portion in Allocate. Release and Compact also need to restore the freeMemPtr and so forth.

[Edit: Thanks to Mage2k for pointing out a typo.]

[edited by - Oluseyi on June 1, 2003 3:44:18 PM]
Hippokrates
Hippokrates
Well, but if I wanted to create an instance of a class now. Would it work?
If this class was derived and the base class had virtual and abstact methods which this class I need an instance of has overridden, would the whole thing work out?
Example:

class c {
public:
c() {}
virtual ~c() {}

virtual int x() {return i;}
virtual void y() = 0;

protected:
int i;
};

class d : public c {
public:
d() {}
~d() {}

void y() {i = 10;}
};

Could I create an instance of d using a memory manager?
Im Anfang war die Tat...Faust
Oluseyi
Oluseyi
Look up placement new.
Mage2k
Mage2k
Also, Oluseyi, your allocate method returns allocMem, which isn''t a variable that''s declared anywhere... Shouldn''t it return allocate, the char* that is set to freeMemPtr before it is incremented?

peace and (trance) out

Mage
---------------------------------------------------There are 10 kinds of people in the world:Those that understand binary, and those that dont...Mage
Oluseyi
Oluseyi
Yes, Mage2k. That was a typo. I changed the variable name from allocMem to allocate, but apparently didn''t get all the references. Thanks.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.