闲来无事,看看游戏精粹。
频繁的分配和删除操作可能会造成许多内存碎片。可能会造成有可以满足程序的内存请求,但却没有足够大的连续的内存块,这样游戏效率很低。
另一个副作用就是低的访问局部性。
下面是一个解决方法的代码:
#include<assert.h>
template<class DataType>
class MemoryAlloc{
public: MemoryAlloc(int Num);
~MemoryAlloc();
private:
MemoryAlloc(MemoryAlloc&otherM);
MemoryAlloc& operator=(MemoryAlloc&);
public:
DataType*NewADataType();
void DeleteDataType(DataType* PData);
protected:
void FreeAll();
DataType * m_PData;
DataType**m_PPData;
int DataBlockNum;
int CurrDataBlockTop;
};
template<class DataType>
MemoryAlloc<DataType>::MemoryAlloc(int Num)
{
DataBlockNum = Num;
FreeAll();
};
template<class DataType>
MemoryAlloc<DataType>::~MemoryAlloc()
{
if(m_PData)
delete []m_PData;
if(m_PPData)
delete []m_PPData;
}
template<class DataType>
void MemoryAlloc<DataType>::FreeAll()
{
assert(DataBlockNum>0);
m_PData = new DataType[DataBlockNum];
m_PPData= new DataType*[DataBlockNum];
assert(m_PData);
assert(m_PPData);
int ITemp = DataBlockNum;
for(CurrDataBlockTop=0;CurrDataBlockTop<DataBlockNum;CurrDataBlockTop++)
{
m_PPData[CurrDataBlockTop] = &(m_PData[--ITemp]);
}
}
template<class DataType>
DataType*MemoryAlloc<DataType>::NewADataType()
{
assert(CurrDataBlockTop);
return m_PPData[--CurrDataBlockTop];
}
template<class DataType>
void MemoryAlloc<DataType>::DeleteDataType(DataType* PData)
{
assert( (PData >= &(m_PData[0])) && (PData <= &(m_PData[DataBlockNum-1])));
assert(CurrDataBlockTop<DataBlockNum); //至少有空位
m_PPData[CurrDataBlockTop++] = PData;
}
下面是测试代码:
int main()
{
MemoryAlloc<int> a(100);
vector<int *> b(100);
for(int i =0 ; i<100;i++)
{
b[i]= a.NewADataType();
}
for(int i =0 ; i<100;i++)
{
a.DeleteDataType(b[i]);
}
b.clear();
b.swap(vector<int*>());
return 0;
}
不过这种实现也有明显的缺陷,在内存管理方面 容易操作上的失误而导致内存的不恰当释放。