2012-07-31 9 views
5

Ho un programma C++ piuttosto grande che include una classe "Character". In "Character.h" prima viene dichiarata la struct CharacterSettings e quindi la classe Character (compresi i loro costruttori).Blocco in caso di aggiunta di variabile pubblica

Il personaggio ha (tra gli altri) un Impostazioni caratteri * e un Punto pos. CharacterSettings ha un Punto preferitoVelocity.

Questo funziona correttamente.

Tuttavia, quando aggiungo una variabile pubblica per personaggio, il programma va in crash quando chiamano questo:

drawLine(character.pos, character.pos+character.settings->preferredVelocity, character.radius/3.0, 128, 80, 0); 

Il programma va in crash su questa linea:

Point operator + (const Point &p2) const 
    { return Point(x + p2.x, y + p2.y); } 

Suppongo che sta cercando di fare character.pos + character.settings-> preferredVelocity. Il messaggio di errore che ottengo è

Unhandled exception at 0x004bc4fc in ECMCrowdSimulation.exe: 0xC0000005: Access violation reading location 0x7f80000f. 

Quando lo guardo, p2.x e p2.y sono indefiniti. Senza la variabile extra, non lo sono. Non ho assolutamente idea di cosa stia succedendo, di come iniziare il debug o di quali informazioni avresti bisogno per aiutarmi! Qualsiasi aiuto sarebbe molto apprezzato!

Modifica: ecco qui almeno il file Character.h!

#pragma once 

/* 
* ECM navigation mesh/crowd simulation software 
* (c) Roland Geraerts and Wouter van Toll, Utrecht University. 
* --- 
* Character: A single moving character in the simulation. 
*/ 

#include "../ECM/GraphComponents/CMNode.h" 
#include "VectorOperation.h" 
#include "IndicativeRoute.h" 
#include "float.h" 

#define _USE_MATH_DEFINES 
#include <math.h> 

#include <vector> 
using std::vector; 
#include <queue> 
using std::queue; 

#define CHARACTER_RELAXATIONTIME 0.5f 

typedef vector<CMNode>::iterator node_ptr; 
class Corridor; 
class CMMResult; 

    struct CMEdge; 
    class CMMInterface; 
    class MicroInterface; 
    class CMMSceneTransfer; 

    struct CharacterSettings 
    { 
    private: 
     bool index_bb_initialized, index_bb_cp_initialized, index_ir_circle_initialized, index_ir_circle_mu_initialized; 
     bool index_2nd_ir_circle_initialized, index_2nd_ir_circle_mu_initialized; 

    public: 
     // --- Unique identifier within the simulation 
     int id; 

     // --- Velocity and speed 
     Point preferredVelocity;// Newly computed velocity *before* local collision avoidance 
     Point newVelocity;  // Newly computed velocity (+ collision avoidance), to be applied in the "next" simulation step 

     float total_max_speed; // Maximum possible speed throughout the entire simulation 
     float max_speed;  // Maximum speed at this point in time 
     float min_desired_speed;// Minimum speed that the character tries to reach when it is not standing still 

     Point lastAttractionPoint; 

     // --- IRM parameters 
     CMMInterface* cmmImplementation; // the type of indicative route to follow within the corridor, e.g. "shortest path" or "weighted side". 
     // Only used in WEIGHTED_SIDE: 
     float sidePreference;  // bias to following a certain "side" of the corridor. Must be between -1 (left) and 1 (right). 
     float sidePreferenceNoise; // extra noise factor that will be added to sidePreference at each route element. 
     // Used in WEIGHTED_SIDE and SHORTEST_PATH 
     float preferred_clearance; // Distance (m) by which the agent prefers to stay away from obstacles. 

     // --- Micro simulation model (e.g. for collision avoidance between characters) 
     MicroInterface* microImplementation;// the local model to use 
     short micro_maxNrNeighbours;  // the number of neighbours to check in the local model 
     float micro_personalSpaceRadius; // radius of the personal space (m), on top of the character's physical radius. 
              // Entering this disk (radius + personalSpace) is seen as a 'collision'. 

     // --- Corridor/Path pointers 
     node_ptr index_bb;   // point on backbone path (used for computing attraction force) 
     node_ptr index_bb_cp;  // point on the backbone path(used for computing the closest point) 
     curve_ptr index_ir_circle; // index to last point on the indicative route that intersects with a circle 
     float index_ir_circle_mu; // factor wrt to point on the indicative route that intersects with a circle 

     friend Character; // only the Character class can look into private members (WvT: ugly C++ practice, but it does work) 

     CharacterSettings(int _id, 
      // speed 
      float _total_max_speed, float _min_desired_speed, 
      // type of indicative route 
      CMMInterface* _cmmImplementation, float _sidePreference, float _sidePreferenceNoise, float _clearance, 
      // type of micro simulation model 
      MicroInterface* _microImplementation) : 

      id(_id), total_max_speed(_total_max_speed), min_desired_speed(_min_desired_speed), 
      cmmImplementation(_cmmImplementation), sidePreference(_sidePreference), sidePreferenceNoise(_sidePreferenceNoise), preferred_clearance(_clearance), 
      microImplementation(_microImplementation) 
     { 
      // velocities 
      newVelocity = Point(0, 0); 
      max_speed = total_max_speed; 
      preferredVelocity = Point(0, 0); 

      // corridor/IRM pointers 
      index_bb_initialized = false; 
      index_bb_cp_initialized = false; 
      index_ir_circle_initialized = false; 
      index_ir_circle_mu_initialized = false; 

      // default micro settings 
      micro_maxNrNeighbours = 5; // default for Karamouzas 2010: 5 
      micro_personalSpaceRadius = 0.0f; // default for Karamouzas 2010: 0.5 
     } 
    }; 

    class Character 
    { 
    public: 
     Point pos; 
     float radius; 
     Point prevPos; 
     int i; //The thing that is pretending to be the culprit, without this, it works fine. 

     // goal data 
     Point goalPos; 
     float goalRadius; 

     // status flags 
     bool reachedGoal; 
     bool freeze; // whether or not the character is temporarily frozen 
     bool freezeNotified; 
     bool reachedDestSet; 

     Point velocity; // last used velocity 

     // corridor/path pointers 
     Point retraction, cp; 

     //Contains more detailed settings of agent 
     CharacterSettings * settings; 

    public: 
     // --- constructor 
     Character(int _id, Point &_pos, float _radius, 
      // speeds 
      float _total_max_speed, float _min_desired_speed, 
      // type of indicative route 
      CMMInterface* _cmmImplementation, float _sidePreference, float _sidePreferenceNoise, float _clearance, 
      // type of micro simulation model 
      MicroInterface* _microImplementation) : 

      pos(_pos), radius(_radius) 
     { 
      settings = new CharacterSettings(_id, _total_max_speed, _min_desired_speed, 
       _cmmImplementation, _sidePreference, _sidePreferenceNoise, _clearance, _microImplementation); 

      velocity = Point(0, 0); 
      prevPos=_pos; 

      reachedGoal = true; 
      freeze = false; 
      freezeNotified = false; 
      reachedDestSet = false; 
      //isProxy = false; 
     } 

     // --- destructor 
     void removeSettings(); 

     // computing the new actual velocity through an acceleration vector: Euler integration 
     inline void integrateEuler(const Point &acc, float dtSim) 
     {     
      settings->newVelocity = velocity + dtSim * acc; 
      trim(settings->newVelocity, settings->max_speed); 
     } 

     inline void updatePos(float dtSim) 
     {  
      prevPos=pos; 

      // update velocity 
      velocity = settings->newVelocity; 

      // update position 
      pos += dtSim * velocity; 

      // if the character is close to its goal, it should stop moving  
      if(!reachedGoal // goal was not already reached 
       && settings->lastAttractionPoint == goalPos 
       && distSqr(pos, goalPos) < 0.25)//goalRadius) 
      { 
       reachedGoal = true; 
       // (do not reset the velocity, so that we can keep the last walking direction) 
      } 
     } 

     void resetIndices(); 
     node_ptr &getIndex_bb(Corridor &corridor); 
     node_ptr &getIndex_bb_cp(Corridor &corridor); 
     curve_ptr &getIndex_ir_circle(IndicativeRoute &ir); 
     float &getIndex_ir_circle_mu(); 
     Point &getRetraction() { return retraction; } 
     Point &getClosestPoint() { return cp; } 

     // computing the cost of some edge (in A*), by using personal preferences 
     float getEdgeCost(const CMEdge& edge, float activeFraction); 

     // computing the character's area, based on its radius 
     float getArea() const; 


    }; 

La cosa che rende tutto in crash è l'aggiunta di "int i".

+0

puoi darci un esempio completo minimo? Cioè, puoi ridurre il codice a un paio di file che sono abbastanza piccoli da postare, che compilano e che riproducono il problema? C'è una buona possibilità che in tal modo scoprirai il bug da solo, e se non lo fai, avremo un vero codice da guardare. – Beta

+0

Puoi postare la definizione di 'Character', invece di descriverla? – hmjd

+0

Temo che alcune parti del codice causino un comportamento indefinito e questo potrebbe causare il blocco del codice in luoghi casuali o "illogici" che potrebbero non essere completamente correlati alla radice del problema. Fornirci un codice minimale che lo riproduca sarebbe di grande aiuto. – ereOn

risposta

8

Solitamente problemi strani come questo si verificano quando si verificano incompatibilità tra i file che sono stati compilati con la versione precedente dell'intestazione collegata a quelli compilati con le versioni più recenti. In questi casi, il layout dell'oggetto può essere diverso (per lo meno, il suo sizeof è diverso) tra i due file.

Pertanto, in un file può sembrare che tutto sia corretto con l'oggetto, ma una volta passato a una funzione in un altro file, si ottiene un comportamento completamente casuale.

In questi casi, la ricostruzione dell'intero progetto risolve il problema. Meglio ancora, prova a correggere le dipendenze se stai scrivendo manualmente i Makefile. Se si utilizza gcc/g ++, è possibile utilizzare un comando come questo per generare Makefile dipendenze accettabili:

g++ -MM -MG -Ipath/to/includes/that/should/be/part/of/dependency *.cpp 
+0

Grazie ancora :). – Tessa

+0

Grazie mille, molto. Stavo per abbandonare il mio progetto perché pensavo che ci fosse qualche tipo di corruzione della memoria o così. Grazie! –

+0

Grazie per la domanda e per la risposta. Ho pensato che stavo impazzendo, l'aggiunta di una semplice variabile ha causato il crollo dell'intero programma in un punto molto strano. E a seconda di dove, in relazione alle altre variabili, ho aggiunto quello nuovo, il punto di schiantarsi era completamente diverso. –

Problemi correlati