C++ 对象的访问冲突

C++ 对象的访问冲突,c++,arrays,oop,pointers,ogre,C++,Arrays,Oop,Pointers,Ogre,我有一个实体。h如下: PxGeometry geometry; if(mMesh == "sphere.mesh") { PxGeometry g = PxSphereGeometry(mDimensions.x / 2); // Because it's a radius geometry = g; } 使用名称空间physx class Entity { public: Entity(Ogre::Vector3 dims, Ogre::Vec

我有一个实体。h如下:

 PxGeometry geometry; 
 if(mMesh == "sphere.mesh")
 {
     PxGeometry g = PxSphereGeometry(mDimensions.x / 2); // Because it's a radius
     geometry = g;  
 } 
使用名称空间physx

class Entity
{

public:
    Entity(Ogre::Vector3 dims, Ogre::Vector3 pos, std::string mesh, std::string id);
    virtual ~Entity(void);
    virtual void update(Ogre::Real dt);
    virtual void init(Ogre::SceneManager* sceneMgr, PxPhysics* physics, PxScene* scene, PxVec3 velocity=PxVec3(0, 0, 0));
protected:
    Ogre::Entity*       mOgreEntity = NULL;
    Ogre::SceneNode*    mOgreNode = NULL;

    Ogre::Vector3       mPosition;
    Ogre::Vector3       mDimensions;
    std::string         mMesh;
    std::string         mId;


    PxRigidDynamic*     mActor;
    PxMaterial*         mMaterial;
};
这是我的实体来源:

#include "Entity.h"

Entity::Entity(Ogre::Vector3 dims, Ogre::Vector3 pos, std::string mesh, std::string id) 
{

    mDimensions = dims;
    mPosition   = pos;
    mMesh       = mesh;
    mId         = id;
    mActor      = NULL;
    mMaterial   = NULL;
}

Entity::~Entity(void)
{

}

void Entity::update(Ogre::Real dt)
{
    PxVec3 pos = mActor->getGlobalPose().p;
    Ogre::Real r = 0;
    mOgreNode->setPosition(Ogre::Vector3(pos.x + r, pos.y + r, pos.z + r));
}

void Entity::init(Ogre::SceneManager* sceneMgr, PxPhysics* physics, PxScene* scene, PxVec3 velocity)
{
    // Create an Entity
    mOgreEntity = sceneMgr->createEntity(mId, mMesh);
    mOgreEntity->setCastShadows(true);

    // Create a SceneNode and attach the Entity to it
    mOgreNode = sceneMgr->getRootSceneNode()->createChildSceneNode(mId + "Node");
    Ogre::AxisAlignedBox box = mOgreEntity->getBoundingBox();
    Ogre::Vector3 realSizes = box.getSize();

    mOgreNode->setPosition(mPosition);
    mOgreNode->attachObject(mOgreEntity);

    Ogre::Vector3 scaler = Ogre::Vector3(mDimensions.x / realSizes.x, mDimensions.y / realSizes.y, mDimensions.z / realSizes.z);
    mOgreNode->scale(scaler);


    mMaterial = physics->createMaterial(1.5f, 1.5f, 1.0f);
    PxGeometry* geometry = NULL;
    if(mMesh == "sphere.mesh")
    {
        PxGeometry g = PxSphereGeometry(mDimensions.x / 2); // Because it's a radius
        geometry = &g;
    } else {
        // geometry = NULL;
    }
    PxTransform transform = PxTransform(PxVec3(mPosition.x, mPosition.y, mPosition.z));
    mActor = PxCreateDynamic(*physics, transform, *geometry, *mMaterial, PxReal(.1));
    // if(!mActor) {
 //        MessageBox( NULL, "no actor", "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
    //  return;
    // }
    mActor->setLinearVelocity(velocity);
    // And add the actor to a scene:

    scene->addActor(*mActor);

}
现在,如果我创建一个实体并初始化它,它就会工作。即使有第二个实体变量,它也可以工作。现在使用数组:

Entity *mEntities[20];
for(int i = 0 ; i < 20 ; i++ ){
    ostringstream nameStream;
    nameStream << "Sphere_" << i;
    string name = nameStream.str();
    Entity* sphere = new Entity(Ogre::Vector3(i*5, i*4.5, i*6), Ogre::Vector3(i*5, i*4.5, i*6), "sphere.mesh", name);
    sphere->init(mSceneMgr, mPhysics, gScene, PxVec3(-10.0f, 0, 0));
    mEntities[i] = sphere;

}
1)

查看
“球体”+i
如果
i
大于“球体”的长度,则将指针传递给某个随机内存。我假设您想创建一个字符串,结尾是I
使用
sprintf
std::string

2)
如果将循环范围从20更改为3,那么它可能会工作。问题是您的姓名将是:
球体,球体,这里 因为通过执行
“Sphere\uu”+i
操作,您并没有将整数添加到字符串中
这等于:

3)
此代码将生成您需要的字符串:

std::ostringstream newStringStream;
newStringStream << "Sphere_" << i;
std::string newString = newStringStream.str();
std::ostringstream newStringStream;
newStringStream还有一个问题:

PxGeometry* geometry = NULL;
if(mMesh == "sphere.mesh")
{
    geometry = &PxSphereGeometry(mDimensions.x / 2); // Because it's a radius
}
这样做的问题是,您正在将临时值的地址指定给
几何体。一旦那一行代码完成,临时代码就消失了

可能的解决方法是:

PxGeometry geometry;
if(mMesh == "sphere.mesh")
{
    geometry = PxSphereGeometry(mDimensions.x / 2); // Because it's a radius
}
//...
mActor = PxCreateDynamic(*physics, transform, geometry, *mMaterial, PxReal(.1));
现在,
geometry
不再是指针,您将几何体指定给返回的值(而不是返回值的地址)

我在这里阅读文档:

因此,
PxSphereGeometry(x)
是一个构造函数调用。因此,您需要将返回值
分配给
PxSphereGeometry
,而不是
PxSphereGeometry*

编辑:您最近的更改也没有达到预期效果:

 if(mMesh == "sphere.mesh")
 {
     PxGeometry g = PxSphereGeometry(mDimensions.x / 2); // Because it's a radius
     geometry = &g;
  } 
g
if()。将此
g
的地址分配给
几何体
。然后,当该块退出时,
g
消失,现在您有了指向不再存在的东西的
几何体

您编辑的代码与我给出的答案之间的区别在于,我的答案
将返回值指定给现有对象。所以我创建了一个返回值的副本。您在编辑的代码中所做的不是创建一个副本,而是指向一个本地对象,正如所解释的,在它离开作用域后,该对象将不存在

因此,如果要编写符合已编辑代码模式的代码,并使其有效,则更改如下所示:

 PxGeometry geometry; 
 if(mMesh == "sphere.mesh")
 {
     PxGeometry g = PxSphereGeometry(mDimensions.x / 2); // Because it's a radius
     geometry = g;  
 } 

然而,这做了一些无关的工作。原来的答案就足够了。

我尝试了另一种创建刚体的方法,它成功了

mActor = physics->createRigidDynamic(PxTransform(PxVec3(mPosition.x, mPosition.y, mPosition.z)));
PxShape* shape = mActor->createShape(PxSphereGeometry(mDimensions.x / 2), *mMaterial);
PxRigidBodyExt::updateMassAndInertia(*mActor, 0.4f);

我建议您在
实体
的构造函数中将指针初始化为NULL。您的代码也绝对不会执行错误检查,以查看您正在调用的函数是否实际返回了良好的值。@PaulMcKenzie感谢您的建议,但我编辑了源代码,仍然收到以下错误:/。参见更新的post
geometry=&PxSphereGeometry(mDimensions.x/2)请解释此行的作用。任何查看它的人都会认为您正在分配一个临时对象的地址,在该语句完成后,这绝对是不好的。呃,我正在创建一个几何变量,其中包含PxCreateDynamics要使用的几何体。错了吗?为什么?再次解释,但使用C++术语。您是否为
geometry
分配临时文件的地址?如果是,那就不好了。感谢字符串,它没有解决访问抖动问题,但它解决了另一个问题,哪一行和哪一次迭代会崩溃?编辑:抱歉,没有正确阅读代码nvm.On-line
mActor->setLinearVelocity(velocity)第一次迭代谢谢,但是PxGeometry没有默认构造函数,这就是为什么使用指针来使用NULL@Vinz243-创建了一个对象,它是一个临时对象,您不能将指针指定给临时对象,并期望该指针在临时对象消失后指向任何有效的对象(这将在该语句结束时发生). 我不知道我能解释得多简单至<代码>PxGeometry几何=PxSphereGeometry(),它可以编译,但我仍然收到访问冲突错误。请将其更改为与我在答案中发布的完全相同。如果您将该语句放在
if(mMesh…
块中,那么您刚才发布的内容也不正确。之所以不正确,是因为现在,
geometry
是临时的,并且在
if()时会消失
block完成。@Vinz243-刚刚看到了您的更改。根据我之前的评论,仍然是错误的。您需要学习
对象生存期
块范围
的基本知识。您在
if()
块中局部声明了
g
。该块一退出,它就会消失。
 PxGeometry geometry; 
 if(mMesh == "sphere.mesh")
 {
     PxGeometry g = PxSphereGeometry(mDimensions.x / 2); // Because it's a radius
     geometry = g;  
 } 
mActor = physics->createRigidDynamic(PxTransform(PxVec3(mPosition.x, mPosition.y, mPosition.z)));
PxShape* shape = mActor->createShape(PxSphereGeometry(mDimensions.x / 2), *mMaterial);
PxRigidBodyExt::updateMassAndInertia(*mActor, 0.4f);