我有一个代码:
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
指针),存在导致程序崩溃的问题。只有当map包含deques时才会发生这种情况,当有列表或向量时,一切正常。可能是什么?
当我使用deques时,这是内存问题。插入调用一堆复制构造函数。
此外,我有一些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 ab
指向那个复制对象的其他指针也指向无效内存(0xcdcdcdcd
&lt; - 感谢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
所以我们所拥有的是对象被破坏,内存被覆盖,并且对象返回到充满垃圾的相同内存(可能是地图数据)。 我用列表和向量替换了deque,两者都运行良好。 所以有一个问题:deque到底发生了什么,或者我做错了,我该如何解决?
修改:这是功能代码:
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
}
}
}
}
这是someClass:
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;
};
};
答案 0 :(得分:1)
我认为你使用insert
使迭代器无效。对于大多数容器,您必须在每次插入后重新设置迭代器值,即:
it = container.insert (it, element);
而不只是:
container.insert (it, element); // it may not be valid anymore
答案 1 :(得分:0)
您已在someClass
中定义了一个复制构造函数,但没有赋值运算符。
只要对象发生“有趣”的事情,您就会泄漏旧值,然后让两个对象指向同一个complexClass
。当第一个删除其指针时,所有副本都将具有无效指针!
尝试复制其中一个无效对象会破坏您所看到的方式。