简体   繁体   中英

0xC0000005: access violation in C++

Here is my code:

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

As you see, I'm trying to use a global (or static ) data, which will call some virtual functions. When I test Base & b = Child(); and in main : b.show(); , everything goes well.

But, if I use map like above, I will get an error:

0xC0000005: Access violatoin reading location 0x00000000 .

I've tried to debug this code and I found that when it arrived myMap.at(0).show(); , I got this:
在此输入图像描述

It seems that the table of virtual functions is Unable to read ...

Then I tried to use the pointer:
map<int, Base *> and {0, new Child()} .
This works.

So it seems that this error comes from temporary reference.

But I don't know why b works. b is a temporary reference too.
In my opinion, this map contains many b .
Why does b works whereas map doesn't work?

You have a map of references to temporaries. I'm surprised that even compiled

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

Drop the reference and switch to unique_ptr

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

You can insert elements into this map using this method . This will prevent object slicing .

You do the same thing again here

Base & b = Child();

You cannot hold non-const references to temporary objects

MSVC does allow to affect a temporary to a reference, meaning that Base & b = Child(); is accepted and correctly processed, even it is not standard C++ and is rejected by other compilers (and could be rejected by a later version of MSVC)

But even MSVC does not accept stl containers of references.

So you should either use a map<int, Base> (no ref, store a copy of the object), or a map<int, Base *> (stores a pointer to the object). In the latter case, you must deal explicitely with the destruction of the object. You can also use smart pointers , unique_ptr or shared_ptr to let the stl cares for automatic destruction.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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