deque的问题:map<...,deque<> >失败,但向量和列表不是?
Problem with deque: map<..., deque<> > fails, but vector and list aren't?
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包含deque时才会发生,当有列表或向量时一切都很好。会是什么呢?
这是内存问题,当我使用deque。Insert调用一堆复制构造函数。另外,我有一些属性someClass
,复制点到内存后,看起来像这样:
0x00959B48 00 000 000 000 000 000 000 000 000 000 000
在错误发生之前(在someClass
的复制构造函数中),这个字段(复制对象)指向这里(相同的地址):
0x00959B48 f0 9b 95 00 000 000 000 000 000
有一个看起来像地址的东西离这里不远(0x00959B48
):
0x00959B0F fd ab ab ab 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 000 000 000 000 000 000
最后回到我们在末尾的
0x00959B48 f0 9b 95 00 000 000 000 000 000
所以我们得到的是对象被销毁,内存被覆盖,对象返回到充满垃圾(可能是映射数据)的相同内存。我用列表和向量替换了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
}
}
}
}
下面是someeclass:
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;
};
};
我认为您使用insert
使迭代器无效。对于大多数容器,每次插入后都必须重新设置迭代器的值,例如:
it = container.insert (it, element);
而不是:
container.insert (it, element); // it may not be valid anymore
在someClass
中定义了复制构造函数,但没有赋值操作符。
一旦对象发生了一些"有趣的"事情,您将泄漏旧值,然后有两个对象指向相同的complexClass
。当第一个对象删除它的指针时,所有的副本都将拥有无效的指针!
试图复制这些无效对象中的一个将破坏您所看到的方式。
- 请解释这句话(cout<<1+int((a<b)^((b-a)&1) )<<endl
- 呼叫运营商<<临时
- 如何防止clang格式在流运算符调用之间添加换行符<<
- <<操作员在下面的行中工作
- Capacity of a deque
- 在调试模式下引发C++ "deque iterator not dereferencable"异常
- C++中deque数据结构的大O是什么?
- 如何使用C++为我的容器 Deque 设置最大大小?
- 为什么 gcc 会给我可能未初始化的警告 deque::insert 带有过滤范围
- C++ deque 消费者总是从生产者那里得到空队列
- Deque 迭代器超出范围
- C++:如何正确地将 deque::front() 返回的变量从函数中传递出去?
- 有没有函数可以在擦除 c++ 中获取 deque.begin() 的 int 值?
- 为什么 deque 比队列快?
- Deque 中元素的随机访问如何提供恒定的时间复杂度?
- 避免在使用链接列表从 deque 中删除最后一个节点时出现内存泄漏
- C++:如何将unique_ptr推送到deque
- 如何显式调用运算符<<
- 获取作为类变量的 Deque 大小时未定义的行为
- 我创建了deque<CObject*>并添加了不同类型的元素。如何更改此元素的属性?