सेग फाल्ट का पता नहीं लगाया जा सकता है, बहुत सारी जानकारी प्रदान की गई है

मैंने इस सवाल को आधे घंटे पहले पूछा था, लेकिन कोड में टाइपो थे और मैं बहुत स्पष्ट नहीं था, इसलिए मैंने हटा दिया है और मैं एक बेहतर प्रारूप के साथ फिर कोशिश कर रहा हूं।

मुझे अपने कोड में सेगमेंटेशन फॉल्ट मिल रहा है, समस्या फ़ंक्शन कॉल if ((* trans) .test ((* this), * (* itr)) में दिखाई देती है) अंदर < कोड> विश्व :: अद्यतन() :

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

प्रसंग:

trans is an iterator for a std::vector conditions where each ICondition has a test(World& world, Enemy& enemy). itr is an iterator through a std::vector that is held by World.

इस फ़ंक्शन में शर्तें वेक्टर भर गया है:

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

    DistFromPlayer LWanderCond1(30);

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

LWander is a state (FState) in my Finite State Machine. Wander is a class that inherits IAction, and setAction accepts an IAction parameter: FState::setAction(IAction iact)

DistFromPlayer is a class that inherits ICondition.

FState::pushCondition(ICondition icond) and FState::pushTransitionState(Fstate state) should take their arguments and push them to Fstate's conditions and states vectors. (A transition's condition and matching target state should be at the same indices in both)

LWander and LRushPlayer are both members of World.


और इसमें सबकुछ शामिल होना चाहिए। मुझे नहीं पता कि मुझे सेगफॉल्ट क्यों मिल रहा है, लेकिन मुझे लगता है कि समस्या यह है कि LWander में World ::itializeStates() में चीजों को कैसे धक्का दिया जाता है । मुझे यह भी ध्यान रखना चाहिए कि मेरे गेम में पहले दुश्मन पैदा होने के बाद सेगफॉल्ट सही होता है, जो एक ही अपडेट फ्रेम है जो (* trans) .test (* this, ** itr) चलाता है पहली बार। सभी दुश्मन s LWander स्थिति में प्रारंभ होते हैं।


ICondition's virtual bool test(World& world, Enemy& enemy); is defined as:

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

and DistFromPlayer's bool test(World& world, Enemy& enemy); is defined as:

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

और केवल डीबगिंग उद्देश्यों के लिए एक प्रिंट स्टेटमेंट होता है।


जीडीबी का बैकट्रैस

#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
0
क्या आप अपना प्रोग्राम जीडीबी (या अन्य डीबगर) और -00 (कोई ऑप्टिमाइज़ेशन) के साथ चला सकते हैं और हमें बैकट्रैक दे सकते हैं?
जोड़ा लेखक klm123, स्रोत
@ जोचिमपिलबोर्ग मैंने इसे कोड :: ब्लॉक के डीबगर के माध्यम से चलाया, और फ़ंक्शन स्टैक मुख्य() -> गेम :: रन() -> गेम :: अपडेट() -> स्टेटस्टैक :: अपडेट() -> जी एंड जेनजे; एमईस्टेट :: अद्यतन() -> और zwnj; विश्व :: अद्यतन() -> ??() जो वास्तव में मैं उम्मीद करता हूं वह वही है। (* trans) को LWander.conditions में पहले तत्व पर सेट किया जाना चाहिए, जो कि public DistFromPlayer: public ICondition और ** itr प्रकार <कोड> सार्वजनिक दुश्मन होना चाहिए
जोड़ा लेखक user3051585, स्रोत
@ klm123 मैंने दूसरी टिप्पणी में फंक्शन स्टैक जोड़ा, लेकिन बीमार ने पूर्ण जीडीबी> बीटी आउटपुट को मूल प्रश्न में डाल दिया।
जोड़ा लेखक user3051585, स्रोत
@ कमांडर मैंने परिवर्तन किया है: std :: vector शर्तें और (* trans) -> test ((* this), * (* itr)) लेकिन मुझे लगता है कि अभी भी सेगफॉल्ट मिल रहा है, इसलिए मुझे लगता है कि उन समस्याओं से संबंधित नहीं थे।
जोड़ा लेखक user3051585, स्रोत
@ कमांडर उस पंक्ति का उद्देश्य <कोड> स्थिति के माध्यम से चलने वाले इटरेटर के समानांतर states के माध्यम से चलने वाला एक पुनरावर्तक होता है। दोनों वैक्टरों में तत्वों की संख्या समान होनी चाहिए, और इससे कोई फर्क नहीं पड़ता कि क्या सीजीएफॉल्ट किसी भी कॉल से पहले किसी भी कॉल से पहले होता है?
जोड़ा लेखक user3051585, स्रोत
मैंने एक <कोड> अगर (ट्रांस! = CurEnemyState.getConditions ()। End() && itr! = MEnemies.end ()) और यह पारित किया, तो ऐसा लगता है कि वे वैध इटरेटर्स दोनों हैं।
जोड़ा लेखक user3051585, स्रोत
@ कमांडर मैंने लूप के दौरान किसी भी समय ट्रांस या इटर इटरेटर्स के वैक्टर को नहीं बदला है। मैंने पूरे <कोड> विश्व :: अपडेट() को दिखाने के लिए पोस्ट संपादित किया
जोड़ा लेखक user3051585, स्रोत
आप कैसे जानते हैं कि "समस्या लगता है इस फ़ंक्शन कॉल पर होना चाहिए"? क्या आपने अपना प्रोग्राम डीबगर में खोजने के लिए चलाया है? यदि हां, तो फ़ंक्शन कॉल स्टैक क्या है? शामिल चर के मूल्य क्या हैं?
जोड़ा लेखक Some programmer dude, स्रोत
आप उस पर सही हो सकते हैं - जब तक आप उन वेक्टरों को कहीं भी स्पर्श नहीं कर रहे हैं, जिन्हें आप यहां नहीं दिखाते हैं, वे आपके लिए ऐसा करने के लिए पर्याप्त सिंक में होना चाहिए, हालांकि यह जोखिम भरा है। वैसे भी, दूसरी समस्या - आप LWander की शर्तों() वेक्टर पर LWanderCond1 को वापस धक्का देते हैं, जो एक व्युत्पन्न वस्तु को अपने माता-पिता के कंटेनर में वापस दबा रहा है - जिसका अर्थ है कि आप सभी को हटा सकते हैं व्युत्पन्न वर्ग के सदस्य चर और कार्यक्षमता के बिना (जैसा कि आप वस्तु को बहुत छोटे कंटेनर में भरते हैं) तो उन सदस्यों तक पहुंचने का प्रयास कर रहे हैं। आपको इसके बजा
जोड़ा लेखक Commander Coriander Salamander, स्रोत
साथ ही, आप ऑब्जेक्टिशन से प्राप्त होने वाले ऑब्जेक्ट्स का एक गुच्छा संग्रहित कर रहे हैं जो आईसींडिशन के वेक्टर में मूल्य से मूल्यवान है - लगता है जैसे आप stackoverflow.com/questions/274626/…
जोड़ा लेखक Commander Coriander Salamander, स्रोत
हम्म। उस ऑटो tState = curEnemyState.getTransitionStates() के बारे में क्या। (); तुरंत अपने लूप से पहले? उस लूप के भीतर एक ++ tState; है, और आप कभी भी जांच नहीं करते कि क्या आपका tState == curEnemyState.getTransitionStates ()। End() किसी भी बिंदु पर - क्या आप संभवतः अग्रिम करते हैं यह समझने के बिना अपने वेक्टर के अंत से पहले iterator?
जोड़ा लेखक Commander Coriander Salamander, स्रोत
यह चिल्लाता है कि 'अमान्य इटरेटर' को अस्वीकार कर रहा है ... क्या आप उन वैक्टरों को संशोधित कर रहे हैं जिनके लिए लूप में किसी भी बिंदु पर ट्रांस और इटर इटरेटर हैं? जब भी आप इसमें हों, तो यह सभी विश्व :: अपडेट() फ़ंक्शन को देखने में सहायक हो सकता है, अगर यह बेहद बड़ा नहीं है
जोड़ा लेखक Commander Coriander Salamander, स्रोत

1 उत्तर

मुझे tState iterator पर संदेह है। आप इसे केवल आरंभ() से शुरू करते हैं और इसे बढ़ाते हैं। मुझे उपयुक्त कंटेनर के अंत() के खिलाफ कोई परीक्षण नहीं मिल रहा है। या यह curEnemyState.getTransitionStates() और curEnemyState.getConditions() के बीच कुछ संबंधों के कारण सुरक्षित है जो मुझे नहीं पता?

0
जोड़ा
मैंने इसे मूल पोस्ट के नीचे जोड़ा। यदि आपके पास समय था और वांछित था, तो हम वीओआईपी पर भी कम्यून कर सकते थे।
जोड़ा लेखक user3051585, स्रोत
क्षमा करें, लेकिन मैं प्रोग्रामिंग के लिए नया हूं, डीबगर का उपयोग करके अकेले रहने दो। Segfault के स्रोत से आपका क्या मतलब है? कोड :: ब्लॉक के अनुसार, जो मुझे लगता है कि जीडीबी का उपयोग करता है, प्रोग्राम (* trans) .test ((* यह), * (* itr)) पर क्रैश हो जाता है) जैसा कि मैंने कहा था। यदि आपका मतलब है कि इनमें से कौन सा पॉइंटर्स इसका कारण बन रहा है, तो मुझे पूरा यकीन है कि (* यह) समस्या नहीं है, और मैं यह पता लगाने की कोशिश कर रहा हूं कि शायद जब मैं शर्तें IConditions या mememies के साथ दुश्मन के साथ, शायद म
जोड़ा लेखक user3051585, स्रोत
शर्तें और states वैक्टरों में समान लंबाई होनी चाहिए, जहां एक शर्त की लक्ष्य स्थिति उसी कोड में states में रखी जाती है क्योंकि स्थिति है शर्तों में। इसलिए यदि मैं उन्हें एक साथ बढ़ाता हूं, तो मेरे पास एक शर्त तक पहुंच है और यह लक्ष्य स्थिति है। हालांकि, यह कोड segfault से संबंधित नहीं है, क्योंकि प्रोग्राम tState पर पहली कॉल से पहले क्रैश हो जाता है।
जोड़ा लेखक user3051585, स्रोत
ठीक है, समझो। Segfault के सटीक स्रोत को जानना उपयोगी हो सकता है। मुझे आपके प्लेटफॉर्म के बारे में निश्चित नहीं है - क्या आप वालग्रिंड (यदि लिनक्स पर हैं) या कुछ वैकल्पिक (यदि विंडोज़ पर हैं) का उपयोग कर सकते हैं?
जोड़ा लेखक Jan Korous, स्रोत
समझा। क्या आप उस आईसींडिशन :: टेस्ट() विधि की परिभाषा प्रदान कर सकते हैं?
जोड़ा लेखक Jan Korous, स्रोत