双端队列问题:map<..., deque<> >失败了,但是向量和列表却没有?
我有一个代码:
typedef map<Coordinate3D, deque<someClass > > someMap;
someMap *newEM;
someMap::iterator iter;
//...
(*newEM)[iter->first].insert((*newEM)[iter->first].end(),
iter->second.begin(), iter->second.end());
旨在合并两个 someMap
。但是存在一个由于内存错误(0xcdcdcdcd
指针)而导致程序崩溃的问题。仅当映射包含双端队列时才会发生这种情况,并且当存在列表或向量时一切正常。可能是什么?
这是我使用双端队列时的内存问题。 Insert 调用一堆复制构造函数。
另外,我还有一些 someClass
属性,在将其复制到内存后,如下所示:
0x00959B48 00 00 00 00 00 00 00 00
就在错误发生之前(在someClass
的复制构造函数中),这个字段(复制对象的)指向这里(相同的地址):
0x00959B48 f0 9b 95 00 00 00 00 00
有一个看起来像离这里不远的地址(0x00959B48
):
0x00959B0F fd ab ab ab ab ab
指向该复制对象的其他指针也指向无效内存(0xcdcdcdcd
<- 感谢调试模式下的 MSVS 指出了这一点)。
然后我为该地址设置内存写入断点(0x00959B48
),这就是我发现的:
msvcr100d.dll!memset...//breakpoint activated here
msvcr100d.dll!_free_dbg_nolock...
msvcr100d.dll!_free_dbg...
msvcr100d.dll!operator delete...
program.exe!someClass::~someClass() Line 294 + 0x21 bytes C++
program.exe!std::swap...
program.exe!std::iter_swap...
program.exe!std::_Reverse...
program.exe!std::reverse...
program.exe!std::deque<...>::_Insert...
program.exe!std::deque<...>::insert...
所以我们所拥有的是该对象的销毁。
msvcr100d.dll!memset...
msvcr100d.dll!_heap_alloc_dbg_impl...
msvcr100d.dll!_nh_malloc_dbg_impl...
msvcr100d.dll!_nh_malloc_dbg...
msvcr100d.dll!operator new...
program.exe!std::_Allocate<std::_Container_proxy>...
program.exe!std::allocator<std::_Container_proxy>::allocate...
program.exe!std::_Deque_val...
program.exe!std::deque<..>::deque<..> >()
program.exe!std::map<...::operator[]
等等值在STL代码中多次改变,如下所示
if (_Right._Myproxy != 0)//<--breaks here
_Right._Myproxy->_Mycont = (_Container_base12 *)&_Right;
:
0x00959B48 08 f6 12 00 00 00 00 00
最后回到我们最后的内容
0x00959B48 f0 9b 95 00 00 00 00 00
所以我们所面临的是对象被销毁,内存被覆盖,并且对象返回到充满垃圾的同一内存(可能是地图数据)。 我用列表和向量替换了双端队列,两者都工作得很好。 所以有一个问题:双端队列到底发生了什么,或者我可能做错了,我应该如何解决这个问题?
编辑:这是功能代码:
void MergeEffectsMaps(EffectsMap **dest, EffectsMap *src) {
EffectsMap *newEM = *dest;
EffectsMap::iterator findIter;
for (EffectsMap::iterator iter = src->begin();
iter != src->end(); iter++) {
findIter = newEM->find(iter->first);
if (findIter != newEM->end()) {//exists
if (!iter->second.empty())
findIter->second.insert(findIter->second.end(),
iter->second.begin(), iter->second.end());
} else {
if (!iter->second.empty()){
(*newEM)[iter->first];
(*newEM)[iter->first].insert((*newEM)[iter->first].end(),
iter->second.begin(), iter->second.end());//<----problem
}
}
}
}
这是一些类:
class someClass {
public:
complexClass1 *value1;
complexClass2 *value2;
float value3;
int value4;
someClass(){
value1=new complexClass1 ();
value2=new complexClass2 ();
value3=0;
value4=0;
};
someClass(const FieldEffect& cp_val){
value1=new complexClass1 (*cp_val.value1);//copy-constructor
value2=new complexClass2 (*cp_val.value2);
value3=cp_val.value3;
value4=cp_val.value4;
};
~someClass(){
delete value1;
delete value2;
};
};
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我认为您正在使用
insert
使迭代器无效。对于大多数容器,您必须在每次插入后重新设置迭代器值,即:而不仅仅是:
I think you are invalidating the iterators with
insert
. For most containers, you have to re-set the iterator value after each insertion, i.e.:instead of just:
您在
someClass
中定义了复制构造函数,但没有定义赋值运算符。一旦对象发生“有趣”的事情,您就会泄漏旧值,然后有两个对象指向同一个
complexClass
。当其中第一个删除其指针时,所有副本都将具有无效指针!尝试复制这些无效对象之一将会破坏您所看到的方式。
You have defined a copy constructor in
someClass
but no assignment operator.As soon as something "interesting" happens to the objects, you will leak the old values and then have two objects pointing to the same
complexClass
. When the first of those deletes its pointer, all the copies will have invalid pointers!Trying to copy one of these invalid objects will break the way you have seen.