c++ - 添加公共(public)变量时崩溃

标签 c++ variables crash

我有一个相当大的 c++ 程序,包括一个类“Character”。在“Character.h”中,首先声明了 CharacterSettings 结构,然后是 Character 类(包括它们的构造函数)。

Character 具有(除其他外)CharacterSettings* 设置和 Point pos。 CharacterSettings 有一个 Point preferredVelocity。

这很好用。

但是,当我将任何公共(public)变量添加到 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'。

最佳答案

当使用旧版本头文件编译的文件与使用新版本编译的文件之间存在不兼容性时,通常会发生此类奇怪的问题。在这种情况下,两个文件的对象布局可能不同(至少,它的 sizeof 不同)。

因此,在一个文件中,对象可能看起来一切都是正确的,但一旦传递给另一个文件中的函数,您就会得到完全随机的行为。

在这种情况下,重建整个项目可以解决问题。更好的是,如果您手动编写 Makefile,请尝试修复依赖关系。如果您使用的是 gcc/g++,则可以使用这样的命令来生成 Makefile 可接受的依赖项:

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

关于c++ - 添加公共(public)变量时崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11739637/

相关文章:

c++ - 具有在编译时定义的不同类型的 vector

Javascript - 如何使 ping 结果始终按照数组变量的原点顺序

html - iPad 3 Webapp 在移动版 Safari 中崩溃

Mysql服务器占用CPU 500%

来自 win32 事件 Hook 的 c++ 回调

c++ - 从 boost 创建的缓冲区访问数据

C编程通过函数传递值

ios - 应用程序仅在IPAD Air上崩溃

c++ - 如何确定二进制字符串的统计随机性?

c++ - 编译器找不到在基类中实现的虚函数