无法弄清楚Seg Fault,提供了大量细节

时间:2013-12-05 08:16:44

标签: c++ segmentation-fault state-machine

我在半小时前问了这个问题,但是代码有错字,而且我不是很清楚,所以我已经删除了,我正在尝试用更好的格式。

我的代码中出现了分段错误,问题似乎出现在if( (*trans).test((*this), *(*itr)) )内的函数调用World::update()中:

void World::update(sf::Time dt)
{
    mPlayer->setVelocity(0.f, 0.f);

    while (!mCommandQueue.isEmpty()){
                Command cmd = mCommandQueue.pop();
                cmd.action(cmd.node, dt);
    }
    mSceneGraph.update(dt);
    adaptPlayerPosition();

    //Enemy Spawn engine
    if (mSpawnTimer.getElapsedTime().asSeconds() >= SPAWN_INTERVAL && mEnemies.size() < MAX_NUM_ENEMIES){
        float winX = mWindow.getDefaultView().getSize().x;
        float winY = mWindow.getDefaultView().getSize().y;
        float x = rand() % (int)winX;
        float y = rand() % (int)winY;
        spawnEnemy(x, y, EnemyType::Loner, IState::ILWander);
        mSpawnTimer.restart();
    }

    // FSM update
    IState::ID curEnemyStateID;
    FState curEnemyState;
    bool trigger = false;
    ICondition triggeredtrans;
    FState triggeredState;
    for(auto itr = mEnemies.begin(); itr != mEnemies.end(); ++itr){
        curEnemyStateID = (*itr)->getState();

        // set curState to whatever the enemy's curState is
        switch(curEnemyStateID){
        case 0:
            curEnemyState = LWander;
            break;
        default:
            break;
        }

        auto tState = curEnemyState.getTransitionStates().begin();
        for(auto trans = curEnemyState.getConditions().begin(); trans != curEnemyState.getConditions().end(); ++trans){
            if( (*trans).test((*this), *(*itr)) ){
                trigger = true;
                triggeredState = (*tState);
                break;
            }
            ++tState;
        }
        if(trigger){
            (*itr)->setState(IState::ILRushPlayer);
            curEnemyState = LRushPlayer;
        }
        curEnemyState.getAction()->doAction((*this), *(*itr));
    }
}

上下文:

transstd::vector<ICondition> conditions的迭代器,其中每个ICondition都有test(World& world, Enemy& enemy)itr是由std::vector<Enemy*>持有的World的迭代器。

conditions向量填充在此函数中:

void World::initializeStates()
{
    Wander LWanderAction;
    LWander.setAction(LWanderAction);

    DistFromPlayer LWanderCond1(30);

    LWander.pushCondition(LWanderCond1);
    LWander.pushTransitionState(LRushPlayer);
}

LWander是我的有限状态机中的状态(FState)。 Wander是继承IAction的类,setAction接受IAction参数:FState::setAction(IAction iact)

DistFromPlayer是一个继承ICondition的类。

FState::pushCondition(ICondition icond)FState::pushTransitionState(Fstate state)应该接受他们的论点并将其推送到Fstate的{​​{1}}和conditions向量。 (转换条件和匹配目标状态应该在两者中的相同索引处)

statesLWander都是LRushPlayer的成员。


这应该涵盖一切。我不知道为什么我会收到SegFault,但我认为问题在于WorldLWander的内容如何被推送到World::initializeStates()。我还应该注意到SegFault是在我的游戏中产生第一个敌人之后发生的,这也是第一次运行(*trans).test(*this, **itr)的更新帧。所有Enemy都以LWander州开头。


ICondition的virtual bool test(World& world, Enemy& enemy);定义为:

bool ICondition::test(World& world, Enemy& enemy){
    return false;
    //returns false by default, overwritten later
}

和DistFromPlayer的bool test(World& world, Enemy& enemy);定义为:

bool DistFromPlayer::test(World& world, Enemy& enemy)
{
    std::cout << "DistFromPlayer (LWander's Transition) was reached\n";
    return false;
}

并且仅包含用于调试目的的print语句。


GDB的回溯

#0  World::update (this=0x6464408, dt=...) at C:\...\World.cpp:97
#1  0x0040416b in GameState::update (this=0x64643f0, dt=...) at C:\...\GameState.cpp:22
#2  0x00402435 in StateStack::update (this=0x28fde0, dt=...) at C:\...\StateStack.cpp:19
#3  0x00403782 in Game::update (this=0x28fbc0, elapsedTime=...) at C:\...\Game.cpp:58
#4  0x004036a2 in Game::run (this=0x28fbc0) at C:\...\Game.cpp:48
#5  0x0040888b in main () at C:\...\main.cpp:7

1 个答案:

答案 0 :(得分:0)

我怀疑是tState迭代器。您只能使用begin()初始化它并递增它。我找不到针对相应容器的end()的任何测试。或者是否因为curEnemyState.getTransitionStates()和curEnemyState.getConditions()之间存在一些关系而无法实现?