我在程序上运行了valgrind,因为我无法弄清楚段错误。它在这里发现了一个问题...
Address 0x75c7670 is 0 bytes inside a block of size 12 free'd
at 0x4024851: operator delete(void*) (vg_replace_malloc.c:387)
by 0x805F6D8: std::list<Object*, std::allocator<Object*>::remove(O
bject* const&) (new_allocator.h:95)
删除是用这种方法......
void ObjectManager::AdjustGridCoord( int x, int y, Object* const obj ) {
// GetTileX and GetTileY guaranteed to be valid indices
int newX = ObjectAttorney::GetTileX( obj );
int newY = ObjectAttorney::GetTileY( obj );
if ( x != newX || y != newY ) {
m_objGrid[x][y].remove( obj );
m_objGrid[newX][newY].push_back( obj );
}
}
我不认为从列表中删除指针会在其上调用delete
。这看起来有什么疑问?如果您需要更多信息,请告诉我们。
P.S。以前在调试时,我注意到发生了问题,因为GetTileX和GetTileY 不是有效索引,并且会返回像13775864这样荒谬的数字。我认为这与delete
问题有关,并且删除或push_back导致了问题。
编辑:这是另一个代码段
for ( unsigned int x = 0; x < m_objGrid.size(); ++x ) {
for ( unsigned int y = 0; y < m_objGrid[x].size(); ++y ) {
for ( ListItr obj = m_objGrid[x][y].begin(); obj != m_objGrid[x][y].end(); ++obj ) {
ObjectAttorney::UpdateAI( *obj );
AdjustGridCoord( x, y, *obj );
}
}
}
AdjustGridCoord可以使迭代器无效吗?
答案 0 :(得分:2)
为了回应你的编辑,是的,我认为你已经正确诊断了它。
您的代码有点令人困惑(主要是因为您将名称obj
赋予对象指针和引用其列表中单元格的迭代器),但是这一行:
m_objGrid[x][y].remove( obj );
删除obj
对象将使调用函数中的obj
迭代器无效。从valgrind输出中可以看出,删除对象会导致列表删除包含对象指针的单元格,这是obj
迭代器引用的内容。因此,obj
迭代器无效。然后,当调用返回时,接下来发生的事情是循环增量:
++obj
这里,obj
是迭代器,它只是在AdjustGridCoord
的调用中被无效并且它的指示单元被删除了。这导致访问被释放的内存,这正是valgrind所抱怨的。
你基本上有两个选择:
AdjustGridCoord
之前获得后续迭代器 2的示例是创建一个std::vector<std::pair<unsigned int, unsigned int> >
,其中包含您需要调用AdjustGridCoord
的坐标,然后对其进行迭代以实际进行调用。
答案 1 :(得分:1)
12个free'd的块实际上是列表节点,而不是你的对象。因此,std::list::remove()
没有在您的指针上调用delete
,只是delete
包含它的列表节点。
我无法从您的代码片段中看出您实际(错误地)使用该内存的地方。