2012-07-31 80 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