2012-07-31 17 views
5

Tengo un programa C++ bastante grande que incluye una clase "Character". En "Character.h" primero se declara struct CharacterSettings, y luego la clase Character (incluyendo sus constructores).Bloqueo al agregar la variable pública

El carácter tiene (entre otros) una configuración CharacterSettings * y una posición de punto. CharacterSettings tiene una Point preferredVelocity.

Esto funciona bien.

Sin embargo, cuando agrego cualquier variable pública de carácter, el programa se bloquea cuando me llaman a esto:

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

El programa se bloquea en esta línea:

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

supongo que está tratando de hacer character.pos + character.settings-> preferredVelocity. El mensaje de error que consigo es

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

Cuando lo miro, y p2.x p2.y no están definidos. Sin la variable adicional, no lo son. ¡No tengo absolutamente ninguna idea de lo que está sucediendo, cómo comenzar a depurar o qué información necesitarías para ayudarme! ¡Cualquier ayuda sería muy apreciada!

Editar: Bueno, aquí está al menos el archivo 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; 


    }; 

Lo que hace que todo se cuelgue es agregar el 'int i'.

+0

¿Puede darnos un ejemplo completo mínimo? Es decir, ¿puede reducir gradualmente el código a un par de archivos lo suficientemente pequeños como para publicarlos, compilarlos y reproducir el problema? Hay una buena posibilidad de que al hacerlo descubras el error tú mismo, y si no lo haces, tendremos un código real para mirar. – Beta

+0

¿Se puede publicar la definición de 'Personaje', en lugar de describirla? – hmjd

+0

Me temo que parte de tu código causa un comportamiento indefinido y esto puede hacer que tu código se cuelgue al azar o en lugares "ilógicos" que pueden no estar relacionados con la raíz del problema. Proporcionarnos un código mínimo que lo reproduzca sería de gran ayuda. – ereOn

Respuesta

8

Por lo general, problemas extraños como este ocurren cuando tiene incompatibilidades entre los archivos compilados con la versión anterior del encabezado y los compilados con las versiones más recientes. En tales casos, el diseño del objeto puede ser diferente (por lo menos, su sizeof es diferente) entre los dos archivos.

Por lo tanto, en un archivo puede parecer que todo está correcto con el objeto, pero una vez que se pasa a una función en otro archivo, se obtiene un comportamiento completamente aleatorio.

En tales casos, la reconstrucción de todo el proyecto resuelve el problema. Mejor aún, intente arreglar las dependencias si está escribiendo manualmente los Makefiles. Si está utilizando gcc/g ++, puede usar un comando como este para generar dependencias aceptables de Makefile:

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

Gracias de nuevo :). – Tessa

+0

Muchas gracias, muchísimo. Estaba a punto de abandonar mi proyecto porque pensé que había algún tipo de corrupción en la memoria más o menos. ¡Gracias! –

+0

Gracias por la pregunta y la respuesta. Pensé que me estaba volviendo loco, y agregué una variable simple que hizo que todo el programa colapsara en un punto muy extraño. Y dependiendo de dónde, en relación con las otras variables, agregué el nuevo, el punto de colisión fue en algún lugar completamente diferente. –

Cuestiones relacionadas