虚函数读取访问冲突

Read Access Violation on Virtual Function

这是我的程序的简化版本。

#include <iostream>
#include <vector>
class Base
{
public:
    Base()
    {

    }

    void virtual update()
    {
        std::cout << "no update function\n";
    }
    void virtual draw()
    {
        std::cout << "no draw function\n";
    }
};

class Derived : public Base
{
public:
    Derived();
    void draw() override;
    void update() override;
};

Derived::Derived()
{

}

void Derived::draw()
{
    std::cout << "draw";
}

void Derived::update()
{
    std::cout << "update";
}

class Caller
{
public:
    Caller();

    void update();
    void draw();

    void reg_obj(Base* obj);
private:
    std::vector<std::shared_ptr<Base>> all_objects;
};

Caller::Caller()
{
    Derived derived_class{};
    reg_obj(&derived_class);
}

void Caller::update()
{
    for (int i = 0; i < all_objects.size(); i++)
    {
        all_objects[i]->update();
    }
}

void Caller::draw()
{
    for (int i = 0; i < all_objects.size(); i++)
    {
        all_objects[i]->draw();
    }
}

void Caller::reg_obj(Base* obj)
{
    all_objects.push_back(std::shared_ptr<Base>{obj});
}

int main()
{
    Caller caller{};

    while (true)
    {
        caller.update();
        caller.draw();
    }
}

此代码有效,但当它在我的完整程序中 caller.update();caller.draw(); 之间时,内存中的 __vfptr 值不会保持不变。当接近 caller.draw() 时,__vfptr 值在调试器的每一步都会发生变化。我不确定如何诊断 __vfptr 中的内存损坏,因为它不是我编写的,而是 C++ 标准的一部分。任何帮助表示赞赏。不,我无法制作可复制的版本。我不知道为什么。我确实努力让它可以重现。

https://youtu.be/yd-76qDa7xc <- 这个视频显示了问题 https://github.com/Sage-King/Alienor <- 非功能代码的来源

Remy Lebeau 的解决方案: Derived derived_class{}; reg_obj(&derived_class); 导致您的其余代码出现未定义的行为。您正在存储一个指向本地对象的指针,该对象随后被销毁,在 all_objects 向量中留下一个悬空指针。您对 all_objects 元素的所有方法调用都作用于无效内存。要解决这个问题,请更改 void reg_obj() 以采用 shared_ptr<Base> 并将其按原样存储,然后更改 Caller() 以使用 std::make_shared() 创建 Derived 对象,就像这样: void Caller::reg_obj(std::shared_ptr<Base> obj) { all_objects.push_back(obj); } Caller::Caller() { reg_obj(std::make_shared<Derived>()); }