1

私はコードをもっている:

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

2つをマージすることを目的としていsomeMapます。0xcdcdcdcdしかし、メモリエラー(ポインタ)が原因でプログラムがクラッシュするという問題があります。これは、マップに両端キューが含まれている場合にのみ発生し、リストまたはベクトルがある場合はすべて正常に機能します。それは何でしょうか?

dequesを使用しているときのメモリの問題があります。Insertは、一連のコピーコンストラクターを呼び出します。someClassまた、ポイントをメモリにコピーした後、次のようなプロパティがあります。

0x00959B48 00 00 00 00 00 00 00 00

エラーが発生する直前(のcopy-constructorでsomeClass)、このフィールド(コピーオブジェクトの)はここ(同じアドレス)を指します:

0x00959B48 f0 9b 95 00 00 00 00 00

ここからそれほど遠くないアドレスのように見えるものがあります(0x00959B48):

0x00959B0F fd ab ab ab ab ab ab ab

その1つのコピーオブジェクトへの他のポインタも無効なメモリを指しています(0xcdcdcdcd<-それを指摘してくれたデバッグモードのMSVSに感謝します)。

次に、そのaddress()にメモリ書き込みブレークポイントを設定し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をlistとvectorに置き換えましたが、どちらも正常に機能しました。それで、質問があります: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;
    };
};
4

2 に答える 2

1

でイテレータを無効にしていると思いますinsert。ほとんどのコンテナでは、挿入するたびにイテレータ値を再設定する必要があります。

it = container.insert (it, element);

ただの代わりに:

container.insert (it, element);  // it may not be valid anymore
于 2011-08-31T12:37:54.803 に答える
0

でコピーコンストラクターを定義しましたsomeClassが、代入演算子は定義していません。

オブジェクトに「興味深い」何かが発生するとすぐに、古い値がリークされ、2つのオブジェクトが同じを指しますcomplexClass。それらの最初のものがそのポインタを削除すると、すべてのコピーに無効なポインタが含まれます!

これらの無効なオブジェクトの1つをコピーしようとすると、これまでの方法が損なわれます。

于 2011-08-31T15:17:59.467 に答える