当你想在你的代码中找到一个错误时,这很难;当你认为你的代码是不会有错误时,这就更难了。

C++-std::map和_crtisvalidheappointer错误

admin 209℃
我尝试将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(),则会得到错误assert\u crtisvalidheappointer…
我用断点检查了一下,我看到,在分配期间(m_map[1]=mydemo;)调用了demo的析构函数,并在delete[]m_array;-如何运行这个函数?

复制构造函数和赋值运算符错误。你需要为 m_array 在做之前 memcpy 是的。当您尝试插入 DEMO 使用 m_map[1] = myDEMO; 正在创建mydemo的副本。创建副本 DEMO 使用类的复制构造函数。因为记忆中 m_array 在执行此复制时未分配 memcpy 通话中断。

将copy-ctor实现建立在赋值运算符的基础上几乎总是错误的。赋值运算符必须删除对象的旧状态并构建新状态。复制ctor只需建立一个新状态。
如果您想这样做,那么您的复制ctor首先需要构建一个默认状态,以供分配运算符崩溃。当然,那是在浪费资源。

也就是说,实际上您应该使用copy and swap习惯用法,将赋值运算符基于dtor和copy-ctor。请参见here以获得对上述内容的更详细解释。

使用std::vector管理字节*.

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

我将代码更改为在映射中的值部分使用指向对象的指针而不是对象:

typedef map<unsigned int,DEMO*> t_mapType;

所以我可以按如下方式协助:

m_map[1] = new DEMO();

我必须使用自己的免费内存方法:

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

转载请注明:我的代码 » C++-std::map和_crtisvalidheappointer错误