Проблема с deque: map <..., deque <>> не работает, но vector и list не? - PullRequest
1 голос
/ 31 августа 2011

У меня есть код:

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).И это происходит только в том случае, если карта содержит запросы, и все отлично работает, когда есть списки или векторы.Что это может быть?

Вот проблема с памятью, когда я использую deques.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 ab ab

Другие указателина этот один копируемый объект также указывают на недопустимую память (0xcdcdcdcd <- спасибо MSVS в режиме отладки за указание на это). </p>

Затем я устанавливаю точку останова записи в память для этого адреса (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
                }
        }
    }
}

Вот какой-то класс:

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

Ответы [ 2 ]

1 голос
/ 31 августа 2011

Я думаю, что вы делаете недействительными итераторы с insert. Для большинства контейнеров вы должны переустанавливать значение итератора после каждой вставки, т.е.

it = container.insert (it, element);

вместо просто:

container.insert (it, element);  // it may not be valid anymore
0 голосов
/ 31 августа 2011

Вы определили конструктор копирования в someClass, но без оператора присваивания.

Как только с объектами происходит что-то «интересное», вы теряете старые значения, а затем получаете два объекта, указывающих на один и тот же complexClass. Когда первый из них удалит свой указатель, все копии будут иметь недопустимые указатели!

Попытка скопировать один из этих недействительных объектов сломает то, что вы видели.

...