我有一个单线程程序,当使用valgrind运行时显示大小为4的无效读取错误。
void
AccountStatus::transmitUpdate(int aiTuples, std::string& astrAliasPidf)
{
std::string lstrPidf;
for (int i=0; i < TOTAL_TUPLE_COMBOS; i++)
{
if (_mSubList[i] != NULL)
{
GuidSubHandlerMap *subHandlerMap = _mSubList[i];
if (this->getPidf (lstrPidf, i+1, aiTuples, astrAliasPidf, false) == -1)
continue;
ACE_DEBUG ((LM_DEBUG, ACCTPRES_DEBUG
"transmitUpdate - created pidf for excludeMask [%X] with tuples [%X]\n", i+1, aiTuples));
GuidSubHandlerMapIter iter;
for (iter = subHandlerMap->begin(); iter != subHandlerMap->end(); iter++) //this line is shown as invalid read
{
subHandlerPtr lpHandler = iter->second;
if (lpHandler)
{
lpHandler->queueNotify (CONTENT_TYPE, lstrPidf);
}
}
}
}
}
在valgrind中显示为具有释放迭代器的函数如下,
void
AccountStatus::removeSubscription (const char *apcSubId, subHandlerPtr apHandler)
{
if (apcSubId && apHandler)
{
int excludeMask = apHandler->excludeMask();
if (excludeMask != 0)
{
if (_mSubList[excludeMask-1] != NULL)
{
GuidSubHandlerMap *subHandlerMap = _mSubList[excludeMask-1];
GuidSubHandlerMapIter iter = subHandlerMap->find (apcSubId);
if (iter != subHandlerMap->end())
{
ACE_DEBUG ((LM_DEBUG, ACCTPRES_DEBUG
"removeSubscription - [%s] mask [%X]\n", apcSubId, excludeMask));
subHandlerMap->erase (iter); //this is where valgrind is showing memory being freed
}
}
}
}
}
Valgrind输出如下,
==9130== Invalid read of size 4
==9130== at 0x9566CC: std::_Rb_tree_increment(std::_Rb_tree_node_base*) (in /usr/lib/libstdc++.so.6.0.8)
==9130== by 0x23A954CD: std::_Rb_tree_iterator<std::pair<std::string const, std::tr1::shared_ptr<ACCOUNT_PRESENCE::subHandler> > >::operator++(int) (stl_tree.h:190)
==9130== by 0x23AB4E01: ACCOUNT_PRESENCE::AccountStatus::transmitUpdate(int, std::string&) (accountStatus.cpp:518)
==9130== Address 0x13604894 is 12 bytes inside a block of size 28 free'd
==9130== at 0x400668A: operator delete(void*) (vg_replace_malloc.c:480)
==9130== by 0x23A9647E: __gnu_cxx::new_allocator<std::_Rb_tree_node<std::pair<std::string const, std::tr1::shared_ptr<ACCOUNT_PRESENCE::subHandler> > > >::deallocate(std::_Rb_tree_node<std::pair<std::string const, std::tr1::shared_ptr<ACCOUNT_PRESENCE::subHandler> > >*, unsigned int) (new_allocator.h:94)
==9130== by 0x23A964B3: std::_Rb_tree<std::string, std::pair<std::string const, std::tr1::shared_ptr<ACCOUNT_PRESENCE::subHandler> >, std::_Select1st<std::pair<std::string const, std::tr1::shared_ptr<ACCOUNT_PRESENCE::subHandler> > >, std::less<std::string>, std::allocator<std::pair<std::string const, std::tr1::shared_ptr<ACCOUNT_PRESENCE::subHandler> > > >::_M_put_node(std::_Rb_tree_node<std::pair<std::string const, std::tr1::shared_ptr<ACCOUNT_PRESENCE::subHandler> > >*) (stl_tree.h:362)
==9130== by 0x23A96513: std::_Rb_tree<std::string, std::pair<std::string const, std::tr1::shared_ptr<ACCOUNT_PRESENCE::subHandler> >, std::_Select1st<std::pair<std::string const, std::tr1::shared_ptr<ACCOUNT_PRESENCE::subHandler> > >, std::less<std::string>, std::allocator<std::pair<std::string const, std::tr1::shared_ptr<ACCOUNT_PRESENCE::subHandler> > > >::destroy_node(std::_Rb_tree_node<std::pair<std::string const, std::tr1::shared_ptr<ACCOUNT_PRESENCE::subHandler> > >*) (stl_tree.h:392)
==9130== by 0x23A97F67: std::_Rb_tree<std::string, std::pair<std::string const, std::tr1::shared_ptr<ACCOUNT_PRESENCE::subHandler> >, std::_Select1st<std::pair<std::string const, std::tr1::shared_ptr<ACCOUNT_PRESENCE::subHandler> > >, std::less<std::string>, std::allocator<std::pair<std::string const, std::tr1::shared_ptr<ACCOUNT_PRESENCE::subHandler> > > >::erase(std::_Rb_tree_iterator<std::pair<std::string const, std::tr1::shared_ptr<ACCOUNT_PRESENCE::subHandler> > >) (stl_tree.h:1189)
==9130== by 0x23A97FA1: std::map<std::string, std::tr1::shared_ptr<ACCOUNT_PRESENCE::subHandler>, std::less<std::string>, std::allocator<std::pair<std::string const, std::tr1::shared_ptr<ACCOUNT_PRESENCE::subHandler> > > >::erase(std::_Rb_tree_iterator<std::pair<std::string const, std::tr1::shared_ptr<ACCOUNT_PRESENCE::subHandler> > >) (stl_map.h:446)
==9130== by 0x23AB5515: ACCOUNT_PRESENCE::AccountStatus::removeSubscription(char const*, std::tr1::shared_ptr<ACCOUNT_PRESENCE::subHandler>) (accountStatus.cpp:314)
正如我提到程序是单线程的,我不知道为什么会出现这个错误。有人可以帮我解决可能导致这种情况的原因吗?
由于
答案 0 :(得分:1)
您没有显示完整的代码,因此很难说,但您应该尽量避免修改正在迭代的容器。
如果您看到this reference page,您会注意到这一行:
擦除元素的引用和迭代器无效。其他引用和迭代器不受影响。
因此,在调用erase
之后,指向已擦除元素的迭代器不再有效,这意味着您无法再使用例如iter++
。