这是某种指针错误吗?

时间:2016-12-02 23:47:13

标签: c++ class pointers crash polymorphism

我在空闲时间制作一款小游戏,在编码时我遇到了一个问题。

我已将此问题隔离开来并尽可能减小:

#include <iostream>
#include <memory>
#include <vector>
#include <Windows.h>
class Base
{
public:
    std::string p;
    virtual ~Base()
    {

    }
    virtual std::vector<std::shared_ptr<std::string>> getText() = 0;
};
class Derived1 : public Base
{
public:
    Derived1()
    {
        p = "from1";
    }
    std::vector<std::shared_ptr<std::string>> getText()
    {
        return std::vector<std::shared_ptr<std::string>>{std::shared_ptr<std::string>(&p)};
    }
};
class Derived2 : public Base
{
public:
    Derived2()
    {
        p = "from2";
    }
    std::vector<std::shared_ptr<std::string>> getText()
    {
        return std::vector<std::shared_ptr<std::string>>{std::shared_ptr<std::string>(&p)};
    }
};
int main()
{
    std::unique_ptr<Base> state;
    std::vector<std::shared_ptr<std::string>> displayText;
    state.reset(new Derived1());
    displayText = state->getText();
    while(1)
    {
        for(auto i = displayText.begin(); i != displayText.end(); ++i)
            std::cout << **i;
        if (GetKeyState('2') < 0)
        {
            state.reset(new Derived2());
            displayText.clear();
            displayText = state->getText();
        }
        else if (GetKeyState('1') < 0)
        {
            state.reset(new Derived1());
            displayText.clear();
            displayText = state->getText();
        }
    }
    return 0;
}

按&#34; 1&#34;和&#34; 2&#34;它来回似乎有时工作,当我退出时,我得到像-1073741510或类似的返回值。在我的游戏代码中,它似乎也崩溃了很多。

(退出我的意思是在命令窗口使用X按钮,抱歉不澄清)

在对unique_ptr和指针进行一些研究以及多态类之后,我仍然无法理解为什么它会像它那样表现。

那么,这里发生了什么?

1 个答案:

答案 0 :(得分:0)

您正在从堆栈变量创建shared_ptr。这将最终调用p上的删除,这是不安全的。见Calling delete on variable allocated on the stack

编辑: 你需要使p指针。您可以执行以下操作:

class Base
{
public:
    std::shared_ptr<std::string> p;
    virtual ~Base()
    {

    }
    virtual std::vector<std::shared_ptr<std::string>> getText() = 0;
};
class Derived1 : public Base
{
public:
    Derived1()
    {
        p = std::make_shared<std::string>("from1");
    }
    std::vector<std::shared_ptr<std::string>> getText()
    {
        return std::vector<std::shared_ptr<std::string>>{p};
    }
};
class Derived2 : public Base
{
public:
    Derived2()
    {
        p = std::make_shared<std::string>("from2");
    }
    std::vector<std::shared_ptr<std::string>> getText()
    {
        return std::vector<std::shared_ptr<std::string>>{p};
    }
};