std::list什么情况下会出现error的错误?
为了对内存的管理,使用了std模板,定义了两个变量:
m_mapMemBusyList用来保存正在使用的内存,m_vecMemFreeList保存未被使用的内存。
其中结构mem_s_info定义如下(这个结构本身可以不用去关心它):
流程如下:
在要分配一个内存时,首先从m_vecMemFreeList中查找是否有对应长度的空闲内存,如果有,就把它从m_vecMemFreeList中移到m_mapMemBusyList中,如果没有,则分配一个新的,然后加入到m_mapMemBusyList中。代码如下:
在删除时,直接把要删除的从m_mapMemBusyList中移到m_vecMemFreeList中即可,代码如下:
环境:vs2010,所以在变量窗口中可以看到ma和list的各项状态,正常情况如下:
失败时如下的形式:
注意,实际的数量有很多,即那些error都是在m_vecMemFreeList的有效个数以内。
初步认为很可能是内存越界导致的,但还不确定
大伙帮忙看下是什么问题导致的,如何定位这种问题
map<int, mem_s_info> m_mapMemBusyList; // 正在使用的内存列表,key为内存地址
list<mem_s_info> m_vecMemFreeList;
m_mapMemBusyList用来保存正在使用的内存,m_vecMemFreeList保存未被使用的内存。
其中结构mem_s_info定义如下(这个结构本身可以不用去关心它):
struct mem_s_info
{
char *pszBuf; // 内存地址
int len; // 内存长度
int id; // 内存的标示号,暂时没什么用处
__time64_t ttCreate; // 创建时间
__time64_t ttAccess; // 最后一次访问时间,即被重新利用的时间
#ifdef _DEBUG
mem_ins_info memIns; // 用于保存分配该内存的代码信息
#endif
};
流程如下:
在要分配一个内存时,首先从m_vecMemFreeList中查找是否有对应长度的空闲内存,如果有,就把它从m_vecMemFreeList中移到m_mapMemBusyList中,如果没有,则分配一个新的,然后加入到m_mapMemBusyList中。代码如下:
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;
}
在删除时,直接把要删除的从m_mapMemBusyList中移到m_vecMemFreeList中即可,代码如下:
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;
}
环境:vs2010,所以在变量窗口中可以看到ma和list的各项状态,正常情况如下:
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]
... ...
注意,实际的数量有很多,即那些error都是在m_vecMemFreeList的有效个数以内。
初步认为很可能是内存越界导致的,但还不确定
大伙帮忙看下是什么问题导致的,如何定位这种问题
...全文
相关推荐
adress_book:Rust中的简单通讯录cli应用程序
同时,Rust鼓励显式处理错误,使用`Result`类型和`?`操作符可以优雅地处理潜在的错误情况。
C++常见问题解答(解决一些常见疑问)
file.eof()) { std::cerr << "Error reading file." << std::endl; } file.close(); ```#### 提高篇33.
C++常见错误及解决方案
#### 五、错误地使用输入输出符**错误信息**: `error C2676: binary ‘>>’: ‘class std::basic_ostream<char, struct std::char_traits
C++程序编译中常见错误资料.pdf
调试器错误信息:error C2447: missing function header (old-style formal list?)。10.
C++常用头文件简介及编译错误大全
这些头文件大部分位于命名空间std中,提供STL(标准模板库)容器如vector、list、map,算法如sort、find,迭代器如forward_list_iterator,以及功能如类型信息的识别


