【问题标题】:Access violation for object对象的访问冲突
【发布时间】:2015-02-10 07:46:39
【问题描述】:

我有一个这样的Entity.h:

使用命名空间 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);

}

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

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;

}

我收到了Access violation。使用即时调试器,结果发现 mActormMaterial 为空

编辑:

此代码也不起作用:

    mEntity = Entity(Ogre::Vector3(50.0f, 50.0f, 50.0f), Ogre::Vector3(50.0f, 40.5f, 60.0f), "sphere.mesh", "sphere");
    mEntity.init(mSceneMgr, mPhysics, gScene, PxVec3(-10.0f, 0, 0));

【问题讨论】:

  • 我建议您在Entity 的构造函数中初始化指向NULL 的指针。您的代码也绝对不会进行错误检查以查看您调用的那些函数是否确实返回了良好的值。
  • @PaulMcKenzie 感谢您的建议,但我编辑了源代码,但仍然收到此错误:/。查看更新后的帖子
  • geometry = &amp;PxSphereGeometry(mDimensions.x / 2); 请解释一下这条线应该做什么。任何人看都会认为你分配的地址是一个临时的,这在声明完成后绝对没有好处。
  • Err,我正在创建一个几何变量,其中包含要由 PxCreateDynamics 使用的几何图形。这是错的吗?为什么?
  • 再次解释,但使用 C++ 术语。您是否将临时地址分配给geometry?如果你是,那就不好了。

标签: c++ arrays oop pointers ogre


【解决方案1】:

1)

Entity* sphere = new Entity(Ogre::Vector3(i*5, i*4.5, i*6), 
                            Ogre::Vector3(i*5, i*4.5, i*6), 
                            "sphere.mesh", 
                            "Sphere_"+i);

"Sphere_"+i 如果i 大于“Sphere_”的长度,则您将指针传递给一些随机内存。我假设您想在最后创建一个带有 i 的字符串。
为此请使用sprintfstd::string

2)
如果您将循环范围从 20 更改为 3,它可能会起作用。问题是你的名字将是:
Sphere_, phere_, 这里_
因为通过执行 "Sphere_"+i 您不会将整数添加到字符串中。
这“等于”:

char *string = "String";
string += 3;

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

std::ostringstream newStringStream;
newStringStream << "Sphere_" << i;
std::string newString = newStringStream.str();

【讨论】:

  • 感谢您提供的字符串,它没有解决访问冲突,但解决了另一个问题
  • 您在哪一行和哪次迭代中遇到了崩溃?编辑:抱歉没有正确读取代码 nvm。
  • 第一次迭代上线mActor-&gt;setLinearVelocity(velocity);
【解决方案2】:

这是另一个问题:

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

问题在于您将临时值的地址分配给geometry。一旦该行代码完成,该临时代码就消失了。

可能的解决方法是这样做:

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 不再是指针,并且您将几何分配给返回的值(不是返回值的地址)。

我在这里阅读文档:

http://docs.nvidia.com/gameworks/content/gameworkslibrary/physx/apireference/files/classPxSphereGeometry.html

所以PxSphereGeometry(x) 是一个构造函数调用。所以你需要将返回的value 分配给PxShpereGeometry,而不是PxSphereGeometry*

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

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

gif() 块的本地。您将此g 的地址分配给geometry。然后当那个块退出时,g 消失了,现在你有 geometry 指向不再存在的东西。

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

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

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

但是,这会做多余的工作。原始答案就足够了。

【讨论】:

  • 谢谢,但是 PxGeometry 没有默认构造函数,这就是为什么使用指针来使用 NULL
  • @Vinz243 - 创建了一个对象,它是一个临时对象,您不能将一个指针分配给一个临时对象,并期望该指针指向任何有效的对象,一旦临时对象消失(这将在该声明结束)。我不知道我能解释得更简单。
  • 好的,我将行从PxGeometry geometry; 更改为PxGeometry geometry = PxSphereGeometry();,它可以编译,但我仍然收到访问冲突错误
  • 请将其更改为 exactly,正如我在答案中发布的那样。如果您将该语句放在 if (mMesh... 块内,您刚刚发布的内容也不正确。它不正确的原因是因为现在,geometry 是临时的,并且会在 if() 块完成时消失。
  • @Vinz243 - 刚刚看到您的更改。根据我之前的评论,仍然是错误的。您需要学习object lifetimesblock scope 的基础知识。您在 if() 块内本地声明了 g。一旦该块退出,它就会消失。
【解决方案3】:

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

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);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-02
    • 1970-01-01
    相关资源
    最近更新 更多