2012-07-31 11 views
5

Mam raczej duży program C++, w tym klasę "Character". W "Character.h" najpierw deklarowane są struct CharacterSettings, a następnie znak klasy (łącznie z ich konstruktorami).Awaria podczas dodawania zmiennej publicznej

Postać ma między innymi ustawienia CharacterSettings * i Point poz. CharacterSettings ma Point preferredVelocity.

To działa dobrze.

Jednak kiedy dodać dowolną zmienną publiczną do charakteru, awarii programu, kiedy nazywają to:

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

awarii programu na tej linii:

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

Zakładam, że próbuje robić character.pos + character.settings-> preferredVelocity. Komunikat o błędzie pojawia się

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

Kiedy patrzę na to, p2.x i p2.y są niezdefiniowane. Bez dodatkowej zmiennej nie są. Nie mam absolutnie pojęcia, co się dzieje, jak rozpocząć debugowanie lub jakich informacji potrzebujesz, aby mi pomóc! Każda pomoc będzie bardzo ceniona!

Edycja: Tutaj jest przynajmniej plik 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; 


    }; 

Rzeczą, która sprawia, że ​​wszystko ulega awarii, jest dodanie "int i".

+0

można dać nam minimalną kompletny przykład? To znaczy, czy możesz zredukować kod do kilku plików, które są wystarczająco małe, aby je opublikować, skompilować i które odwzorowują problem? Jest duża szansa, że ​​sam to odkryjesz, a jeśli nie, będziemy mieli prawdziwy kod, na który możemy zwrócić uwagę. – Beta

+0

Czy możesz opisać definicję "Postaci" zamiast jej opisywać? – hmjd

+0

Obawiam się, że jakiś fragment kodu powoduje niezdefiniowane zachowanie, co może spowodować awarię twojego kodu w przypadkowych lub "nielogicznych" miejscach, które mogą być całkowicie niezwiązane z źródłem problemu. Zapewnienie nam minimalnego kodu, który powielałby, bardzo by pomogło. – ereOn

Odpowiedz

8

Zazwyczaj dziwne problemy, takie jak te, występują w przypadku niezgodności między plikami skompilowanymi ze starszą wersją nagłówka powiązaną z kompilacją w nowszych wersjach. W takich przypadkach układ obiektu może być inny (w każdym razie jego sizeof jest inny) między dwoma plikami.

Dlatego w jednym pliku może wyglądać, że wszystko jest poprawne z obiektem, ale po przejściu do funkcji w innym pliku, otrzymujesz całkowicie losowe zachowanie.

W takich przypadkach przebudowanie całego projektu rozwiązuje problem. Co więcej, spróbuj naprawić zależności, jeśli ręcznie piszesz pliki Makefile. Jeśli używasz gcc/g ++, można użyć polecenia tak, aby wygenerować Makefile dopuszczalne zależności:

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

Jeszcze raz dziękuję :). – Tessa

+0

Dziękuję bardzo, bardzo. Miałem zamiar rzucić mój projekt, ponieważ myślałem, że było coś w rodzaju korupcji pamięci. Dzięki! –

+0

Dziękuję za pytanie i za odpowiedź. Myślałem, że zwariowałem, a dodanie jednej prostej zmiennej spowodowało, że cały program zawalił się w bardzo dziwnym miejscu. I w zależności od tego, gdzie w stosunku do innych zmiennych, które dodałem do nowego, punkt zawalenia był gdzieś zupełnie inny. –

Powiązane problemy