开发者

Problem with deque: map<..., deque<> > fails, but vector and list aren't?

开发者 https://www.devze.com 2023-04-01 05:01 出处:网络
I have a code: typedef map<Coordinate3D, deque<someClass > > someMap; someMap *newEM; someMap::iterator iter;

I have a code:

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());

that intended to merge two someMap. But there is a problem that crashes program due to memory errors(0xcdcdcdcd pointer). And that is happening only if map contains deques, and everything works fine when there are lists or vectors. What might it be开发者_如何学JAVA?

Here is memory problem when I'm using deques. Insert calls a bunch of copy-constructors. Also I have some property of someClass that after copying points to memory that looks like this:

0x00959B48 00 00 00 00 00 00 00 00

Right before error occures(in copy-constructor of someClass), this field(of copying object) points here(same address):

0x00959B48 f0 9b 95 00 00 00 00 00

There is something that looks like address not far away from here(0x00959B48):

0x00959B0F fd ab ab ab ab ab ab ab

Other pointers to that one copying object also point on invalid memory(0xcdcdcdcd <- thanks MSVS in debug mode for pointing that out).

Then I set memory write breakpoint for that address(0x00959B48) and thats what I found:

 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...

So what we have is destruction of that object.

 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[]

and so on value several times changes inside STL code like this:

if (_Right._Myproxy != 0)//<--breaks here
        _Right._Myproxy->_Mycont = (_Container_base12 *)&_Right;

into this

0x00959B48 08 f6 12 00 00 00 00 00

and finally back to what we have at the end

0x00959B48 f0 9b 95 00 00 00 00 00

So what we have is object being destroyed, memory overwritten, and object goes back to the same memory filled with garbage(which is probably map data). I substituted deque with list and vector and both worked fine. So there is a question: what the hell happened with deque, or maybe I'm doing this wrong way and how should I resolve this?

Edit: Here is function code:

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
                }
        }
    }
}

Here is 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;
    };
};


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.:

it = container.insert (it, element);

instead of just:

container.insert (it, element);  // it may not be valid anymore


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号