2012-07-31 74 views
5

我有一個相當大的C++程序,包括一個類「字符」。在「Character.h」中,首先聲明結構CharacterSettings,然後聲明類Character(包括它們的構造函數)。添加公共變量時崩潰

角色有(其中包括)CharacterSettings *設置和Point pos。 CharacterSettings有一個Point preferredVelocity。

這工作正常。

然而,當我加入任何公開的變量添加到角色中,程序崩潰時我稱之爲:

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

該行的程序崩潰:

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

我以爲它試圖做character.pos + character.settings-> preferredVelocity。我得到的錯誤信息是

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

當我看它時,p2.x和p2.y是未定義的。沒有額外的變量,他們不是。我完全不知道發生了什麼,如何開始調試或需要哪些信息來幫助我!任何幫助將不勝感激!

編輯:那麼這裏至少是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; 


    }; 

讓所有事情都崩潰的事情是添加'int i'。

+0

你能不能給我們一個完整的最小的例子嗎?也就是說,你是否可以將代碼減少到幾個足夠小的文件以進行編譯並重現問題?有這樣一個很好的機會,你會發現自己的錯誤,如果你不這樣做,我們將有真正的代碼來看待。 – Beta 2012-07-31 12:05:13

+0

你可以發佈'Character'的定義,而不是描述它嗎? – hmjd 2012-07-31 12:05:25

+0

恐怕有一段代碼導致了未定義的行爲,這可能會導致您的代碼隨機崩潰或「不合邏輯」的地方,這可能與問題的根源完全無關。向我們提供一個重現它的最小代碼將會有很大幫助。 – ereOn 2012-07-31 12:06:35

回答

8

這樣的奇怪問題發生在您使用較舊版本的頭文件與使用較新版本編譯的頭文件編譯的文件之間不兼容時。在這種情況下,這兩個文件之間的對象佈局可能會有所不同(至少它的sizeof是不同的)。

因此,在一個文件中它可能看起來像對象一切都正確,但是一旦傳遞給另一個文件中的函數,就會得到完全隨機的行爲。

在這種情況下,重建整個項目解決了這個問題。更好的是,如果您正在手動編寫Makefiles,請嘗試修復依賴關係。如果你正在使用gcc /克+ +,你可以用這樣的命令生成的Makefile可接受的依賴關係:

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

再次感謝:)。 – Tessa 2012-07-31 12:57:42

+0

非常非常感謝。我正要放棄我的項目,因爲我認爲存在某種內存損壞等等。謝謝! – 2014-08-08 03:16:22

+0

感謝您的問題和答案。我以爲我瘋了,添加一個簡單的變量導致整個程序崩潰在一個非常奇怪的點。取決於與其他變量相關的地方,我添加了新的變量,崩潰點完全不同。 – 2015-08-13 13:40:17