使用std ::指针时的Segfault ...任何人都可以解释这个吗?

时间:2011-08-13 17:34:54

标签: c++ inheritance pointers segmentation-fault

在我的游戏中,我创建了一个名为Entity的基类,我将其存储在一个集合中进行处理。我的所有游戏对象都来自这个类,我在初始化函数中将派生指针类型添加到集合中没有问题。

问题在于从实体的Step()函数中添加新元素。现在,在我深入研究之前,我将向您展示一些简化的代码:

class GameState
{
    public:
        GameState();
        ~GameState();
        ...
        set<Entity*> entities;
        void Add(Entity* e);
        void Remove(Entity* e);
    protected:
        set<Entity*> added, removed;
};

class Entity
{
    public:
        Entity();
        Entity(GameState* parent);
        virtual ~Entity();
        virtual void Step(const sf::Input& input);
        ...
        virtual void Destroy();
    protected:
        GameState* game;
};

GameState中的添加和删除功能只需将参数 e 分别添加到addedremoved集。在主循环(GameState中的其他位置)中,我在处理之前将元素从added移动到entities,在处理之后,我从removed中删除entities中的元素。这可确保在迭代期间不会修改entities

添加/删除功能非常简单:

void GameState::Add(Entity* e)
{
    added.insert(e);
}

void GameState::Remove(Entity* e)
{
    removed.insert(e);
}

每个派生的实体都在其构造函数中传递一个指向GameState的指针,它保持为game。因此从理论上来说,从Step函数我应该可以使用像game->Remove(this);之类的简单调用来添加和删除实体,但我得到了段错误。经过一夜的谷歌搜索,没有任何结果,我能够通过实施Entity::Destroy()来解决问题(部分):

void Entity::Destroy()
{
    game->Remove(this);
}

所以我的第一个问题是:当我在基类中而不是在派生类中时,this为什么会起作用?

对我来说更令人费解的是Add()。为什么Add(new Explosion(16,16,this))在GameState中工作但game->Add(new Explosion(16,16,game))在我的对象中不起作用?

我通过gdb运行它告诉我:

Program received signal SIGSEGV, Segmentation fault.
At c:/program files (x86)/codeblocks/mingw/bin/../lib/gcc/mingw32/4.4.1/include/c++/bits/stl_tree.h:482

抛出错误的代码是:

_Link_type
  _M_begin()
  { return static_cast<_Link_type>(this->_M_impl._M_header._M_parent); } //this line

总而言之,我不知道为什么我的指针打破了STL ...我感到严重的感觉我错过了一些非常基本的东西,并且引起了所有这些令人头疼的问题。谁能给我建议?

1 个答案:

答案 0 :(得分:1)

  

为什么Add(new Explosion(16,16,this))可以在GameState中工作,但是   game->Add(new Explosion(16,16,game))在我的对象中不起作用?

如果是这种情况,则唯一可能的解释是Entity的{​​{1}}成员实际上并未指向game。在使用之前检查它是否正确设置并验证。

这与GameState无关。问题是您正在使用std::set,它是您通过损坏的指针访问的类的一部分。