0xC0000005:C ++中的访问冲突

时间:2015-07-30 11:53:12

标签: c++ virtual

这是我的代码:

class Base
{
public:
    virtual void show() const = 0;
};

class Child : public Base
{
private:
    static const int i = 1;
public:
    virtual void show() const
    {
        cout << i;
    }
};

map<int, const Base &> myMap{
    { 0, Child() },
    { 1, Child() },
};

Base & b = Child();

int main()
{
    b.show();

    myMap.at(0).show(); // This provokes the error

    system("pause>NUL");
    return 0;
}

如您所见,我尝试使用global(或static)数据,这些数据会调用某些virtual个函数。当我测试Base & b = Child();mainb.show();时,一切顺利。

但是,如果我像上面那样使用map,我会收到错误:

  

0xC0000005: Access violatoin reading location 0x00000000

我已尝试调试此代码,我发现当它到达myMap.at(0).show();时,我得到了这个:
enter image description here

似乎虚函数表是Unable to read ...

然后我尝试使用指针:
map<int, Base *>{0, new Child()}
这很有效。

所以看来这个错误来自临时参考。

但我不知道为什么b有效。 b也是临时参考 在我看来,这个map包含许多b 为什么b有效,而map无效?

2 个答案:

答案 0 :(得分:6)

你有一个临时参考地图。我甚至惊讶于编译

map<int, Base &> myMap{
    { 0, Child() },
    { 1, Child() },
};

删除参考并切换到unique_ptr

std::map<int, std::unique_ptr<Base>> myMap;

您可以在此地图using this method中插入元素。这会阻止object slicing

你在这里再做同样的事情

Base & b = Child();

You cannot hold non-const references to temporary objects

答案 1 :(得分:0)

MSVC允许影响临时参考,这意味着Base & b = Child();被接受并正确处理,即使它标准C ++并被其他编译器拒绝(并且可能是被更高版本的MSVC拒绝

但即使是MSVC也不接受stl容器的引用。

因此,您应该使用map<int, Base>(无参考,存储对象的副本)或map<int, Base *>(存储指向对象的指针)。在后一种情况下,必须明确地处理对象的破坏。您还可以使用智能指针unique_ptrshared_ptr让stl关注自动销毁。