クラス「キャラクター」を含むかなり大きなC++プログラムがあります。"Character.h" では、最初に構造体 CharacterSettings が宣言され、次にクラス Character (コンストラクターを含む) が宣言されます。
Character には (とりわけ) CharacterSettings* 設定と Point pos があります。CharacterSettings には Point preferredVelocity があります。
これはうまくいきます。
ただし、パブリック変数を Character に追加すると、これを呼び出すとプログラムがクラッシュします。
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」を追加することです。