繁体   English   中英

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

[英]0xC0000005: access violation in C++

这是我的代码:

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(); , 我懂了:
在此输入图像描述

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

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

所以似乎这个错误来自临时引用。

但我不知道为什么b有效。 b也是临时参考。
在我看来,这张map包含很多b
为什么b工作而map不起作用?

你有一个临时工具的地图。 即使编译,我也很惊讶

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

删除引用并切换到unique_ptr

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

您可以使用此方法将元素插入此贴图中。 这将阻止对象切片

你在这里再做同样的事情

Base & b = Child();

您不能保存对临时对象的非const引用

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM