16,472
社区成员
发帖
与我相关
我的任务
分享
map<int, mem_s_info> m_mapMemBusyList; // 正在使用的内存列表,key为内存地址
list<mem_s_info> m_vecMemFreeList;
struct mem_s_info
{
char *pszBuf; // 内存地址
int len; // 内存长度
int id; // 内存的标示号,暂时没什么用处
__time64_t ttCreate; // 创建时间
__time64_t ttAccess; // 最后一次访问时间,即被重新利用的时间
#ifdef _DEBUG
mem_ins_info memIns; // 用于保存分配该内存的代码信息
#endif
};
char *CMemoryManagerS::CreateMem( const int len, const char* file /*= NULL*/, const char *function /*= NULL*/, const int line /*= 0*/ )
{
if ( len < 0 || len > 0x4000000 )
return NULL;
// 如果为0,则也分配8个字节
int startlen = len;
if ( len == 0 )
startlen = 1;
mem_s_info *pstuSInfo;
char *pReturnPtr = NULL;
list<mem_s_info>::iterator iterFree;
CAutoCri criFree( m_csMemBusy);
for ( iterFree = m_vecMemFreeList.begin(); iterFree != m_vecMemFreeList.end(); iterFree++ )
{
pstuSInfo = &(*iterFree);
if ( pstuSInfo->len <= startlen )
continue;
if ( pstuSInfo->len > startlen * 5/4 && pstuSInfo->len >= 32 )
{
// 比需求内存大的最小内存,比需求内存大了1/4,所以为了节约,重新进行申请,防止过分地浪费内存。
break;
}
// 搞定
pstuSInfo->ttAccess = _time64(NULL);
memset( pstuSInfo->pszBuf, 0, pstuSInfo->len );
// 把此条记录移到使用列表中
pReturnPtr = pstuSInfo->pszBuf;
#ifdef _DEBUG
SetMemIns( pstuSInfo, file, function, line );
#endif
m_mapMemBusyList[(int)pReturnPtr] = *pstuSInfo;
m_vecMemFreeList.erase( iterFree );
return pReturnPtr;
}
criFree.Release();
// 需要分配新的内存。弄成8字节对齐,估计运行的效率会高一些
int irelen = startlen + 8; // 不是+7,目的是要使分配出来的内存一定比实际指定的要大,最多大8个字节,最少大1个字节
irelen /= 8;
irelen *= 8;
mem_s_info stuSInfo;
stuSInfo.pszBuf = new char[irelen];
stuSInfo.len = irelen;
CAutoCri criCounter( m_csIDCounter );
stuSInfo.id = m_memIDCounter++;
criCounter.Release();
stuSInfo.ttCreate = _time64(NULL);
stuSInfo.ttAccess = stuSInfo.ttCreate;
if ( stuSInfo.pszBuf == NULL )
{
return NULL; // 分配失败
}
memset( stuSInfo.pszBuf, 0, stuSInfo.len );
#ifdef _DEBUG
SetMemIns( &stuSInfo, file, function, line );
#endif
CAutoCri criBusy2( m_csMemBusy );
m_mapMemBusyList[(int)stuSInfo.pszBuf] = stuSInfo;
criBusy2.Release();
return stuSInfo.pszBuf;
}
UINT32 CMemoryManagerS::DeleteMem( const char *pmemAddress )
{
map<int, mem_s_info>::iterator iter;
list<mem_s_info>::iterator iterFree;
mem_s_info memInfo = {0};
CAutoCri criBusy( m_csMemBusy);
iter = m_mapMemBusyList.find( (int)pmemAddress );
if ( iter == m_mapMemBusyList.end() )
{
return errorcode_MEM_DELETEALREADY;
}
// 把它从使用表中移到未使用的列表中,并修改访问时间
memInfo = iter->second;
memInfo.ttAccess = _time64(NULL);
m_mapMemBusyList.erase( iter );
cntBusy = m_mapMemBusyList.size();
// 注意,必需先使用,然后再删除。注意必需按照从小到大的顺序插入进去
iterFree = m_vecMemFreeList.begin();
while ( iterFree != m_vecMemFreeList.end() )
{
if ( iterFree->len < memInfo.len )
{
iterFree++;
continue;
}
break;
}
m_vecMemFreeList.insert( iterFree, memInfo );
criBusy.Release();
ShinkList(); // 这一行用于删除m_vecMemFreeList中停留时间过长的那些内存,在出问题时此代码未生效,所以本贴说的问题和此函数无关
return errorcode_SUCCESS;
}
m_vecMemFreeList [0] 结构mem_s_info的各字段值
[1] 结构mem_s_info的各字段值
[2] 结构mem_s_info的各字段值
[3] 结构mem_s_info的各字段值
... ...
m_vecMemFreeList [0] 结构mem_s_info的各字段值
[1] 结构mem_s_info的各字段值
[2] 结构mem_s_info的各字段值
[error]
[error]
[error]
... ...