std::list 删除在指针上调用删除?
由于我无法弄清楚的段错误,我在程序上运行了 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
。这里看起来有什么可疑的吗?如果您需要更多信息,请告诉我。
PS 以前在调试此问题时,我注意到出现问题是因为 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 是否会使迭代器无效?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
针对您的编辑,是的,我认为您的诊断是正确的。
您的代码有点令人困惑(主要是因为您将名称
obj
指定给对象指针和引用列表中其单元格的迭代器),但是这一行:您删除了
obj
对象将使调用函数中的obj
迭代器失效。正如您从 valgrind 输出中看到的,删除对象会导致列表删除保存对象指针的单元格,这就是 obj 迭代器所引用的内容。因此,obj迭代器无效。然后,当调用返回时,接下来发生的事情是循环增量:这里,
obj
是迭代器,它刚刚失效,并且在对AdjustGridCoord< 的调用中删除了其引用单元格。 /代码>。这会导致对已释放内存的访问,这就是 valgrind 所抱怨的。
您基本上有两个选择:
AdjustGridCoord
之前获得后续迭代器2 的一个例子是创建一个
std::vector 。 >
保存您需要调用AdjustGridCoord
的坐标,然后对其进行迭代以实际进行调用。In response to your edit, yes, I think you have diagnosed it correctly.
Your code is a bit confusing (mainly because you give the name
obj
to both an object pointer and the iterator referring to its cell in the list), but this line:where you remove the
obj
object will invalidate theobj
iterator in the calling function. As you can see from the valgrind output, removing the object cause the list to delete the cell holding the object pointer, which is what theobj
iterator refers to. Thus, theobj
iterator is invalidated. Then, when the call returns, the very next thing that happens is the loop increment:Here,
obj
is the iterator, which was just invalidated and its referent cell deleted within the call toAdjustGridCoord
. This causes an access to memory that was deallocated, which is what valgrind is complaining about.You essentially have two options:
AdjustGridCoord
An example of 2 would be to create a
std::vector<std::pair<unsigned int, unsigned int> >
that holds the coordinates that you need to callAdjustGridCoord
on, and then iterate over that to actually make the calls.释放的大小为 12 的块实际上是列表节点,而不是您的对象。因此,
std::list::remove()
并未对指针调用delete
,它只是删除
包含它的列表节点。我无法从您的代码片段中看出您实际上(错误地)使用了该内存的位置。
The block of size 12 free'd is actually the list node, not your object. So,
std::list::remove()
didn't calldelete
on your pointer, it simplydelete
d the list node containing it.I can't tell from your code snippets where you actually (wrongly) use that memory.