0

std::map を使用しようとしています

class DEMO {
    public:
        DEMO();
        virtual ~DEMO();
        DEMO &operator =(const DEMO &d);
        DEMO(const DEMO& d);
        BYTE* Arr() const;
    private:
        BYTE *m_array;
};

DEMO &DEMO::operator =(const DEMO &d) {
    memcpy(m_array, d.Arr(), 1);
    return *this;
}

DEMO::DEMO(const DEMO& d) {
    //call operator=
    *this = d;
}

const BYTE* DEMO::Arr() const {
    return m_array;
}

DEMO::DEMO() {
    m_array = new BYTE[1];
    }

DEMO::~DEMO() {
    if (m_array != 0)
        delete [] m_array;
}

class MyClass {
    private:
        typedef map<unsigned int,DEMO> t_mapType;
        t_mapType m_map;
        void Test();
}

void MyClass::Test() {
    DEMO myDEMO;
    m_map[1] = myDEMO;
}

クラス内で Test() を呼び出すと、_CrtIsValidHeapPointer をアサートするエラーが発生します...
ブレークポイントでチェックしたところ、割り当て中に (m_map[1] = myDEMO;) DEMO のデストラクタが呼び出され、エラーが発生しました[] m_array を削除します。- これを実行するにはどうすればよいですか?

4

4 に答える 4

4

コピー コンストラクターと代入演算子が間違っています。m_arrayを行う前にメモリを割り当てる必要がありますmemcpy。myDEMOのコピーDEMOを使用してマップにオブジェクトを挿入しようとすると、作成されます。コピーを作成するには、クラスのコピー ctor が使用されます。このコピーの実行中にメモリが割り当てられていないため、呼び出しがクラッシュしています。m_map[1] = myDEMO;DEMOm_arraymemcpy

于 2010-08-25T08:27:55.583 に答える
1

代入演算子に基づいてコピー ctor の実装を行うことは、ほとんどの場合間違っています。代入演算子は、オブジェクトの古い状態を破棄し、新しい状態を構築する必要があります。copy ctor は、新しい状態を構築するだけで済みます。このようにしたい
場合、copy ctor は最初に代入演算子が分解するデフォルト状態を構築する必要があります。もちろん、それは資源の浪費です。

とはいえ、実際には、代わりにコピーアンドスワップイディオムを使用して、代入演算子を dtor とコピー ctor に基づいて作成する必要があります。上記の詳細な説明については、こちらを参照してください。

于 2010-08-25T10:19:59.167 に答える
0

std::vector を使用して BYTE* を管理します。

class DEMO {
    public:
        DEMO();
        virtual ~DEMO();
        //DEMO &operator =(const DEMO &d);
        //DEMO(const DEMO& d);
        const std::vector<BYTE>& Arr() const;
    private:
        std::vector<BYTE> m_array;
};

// Doesn't even need to be implemented by us anymore
//DEMO &DEMO::operator =(const DEMO &d) {
//    memcpy(m_array, d.Arr(), 1);
//    return *this;
//}

// Again, doesn't need to be implemented
//DEMO::DEMO(const DEMO& d) {
//    //call operator=
//    *this = d;
//}

// Just changed to return const vector&.
const std::vector<BYTE>& DEMO::Arr() const {
    return m_array;
}

// Changed to use initializer list
DEMO::DEMO() 
    : m_array(1) {
    // Old code: m_array = new BYTE[1];
}

// Doesn't need any code by us
DEMO::~DEMO() {
    //if (m_array != 0)
    //    delete [] m_array;
}
于 2010-08-25T10:25:35.097 に答える
0

マップの値部分にオブジェクトではなくオブジェクトへのポインターを使用するようにコードを変更しました。

typedef map<unsigned int,DEMO*> t_mapType;

だから私は次のように推測することができます:

m_map[1] = new DEMO();

独自の free-mem メソッドを使用する必要があります。

void DEMO::Clear() {
    if (m_map.size() > 0) {
        for (t_mapType::const_iterator it = m_map.begin(); it != m_mp.end(); ++it) {
            if (it->second != 0)
                delete it->second;
        }
        m_map.clear();
    }
}
于 2010-08-25T10:43:32.577 に答える