我在这里遇到一个对我来说很奇怪的问题,我特意改变了我的程序,使得它使用动态内存,因为我之前收到了堆栈错误。内存密集型部分已经变为动态,但我仍然会出现堆栈溢出,而我预计堆溢出,但是我有足够的RAM,所以即使那些也不应该发生。
标题文件:
#ifndef __FPS_h_
#define __FPS_h_
#include "BaseApplication.h"
#include <Ogre/OgreLogManager.h>
#include <Ogre/OgreInstanceManager.h>
#include <btBulletDynamicsCommon.h>
#include <btIDebugDraw.h>
#include "BtOgreExtras.h"
#include "BtOgreGP.h"
#include "btOgrePG.h"
class FPS : public BaseApplication
{
public:
FPS(void);
virtual ~FPS(void);
protected:
virtual void createScene(void);
virtual void createCamera(void);
virtual void createViewports(void);
virtual bool frameRenderingQueued(const Ogre::FrameEvent &evt);
void initializePhysics(void);
void initializeGraphics(void);
void initializeGraphicsBase(void);
void initializeGraphicsGround(void);
void initializeGraphicsTiles(void);
void initializeGraphicsRobot(void);
private:
Ogre::InstanceManager* tileInstanceManager;
Ogre::SceneNode*** tileSceneNode[300][300];
btRigidBody*** tileRigidBody[300][300];
//Ogre::SceneNode* tileSceneNode;
//btRigidBody* tileRigidBody;
Ogre::SceneNode* robotSceneNode;
btRigidBody* robotRigidBody;
btDiscreteDynamicsWorld* dynamicsWorld;
BtOgre::DebugDrawer* debugDrawer;
};
#endif // #ifndef __FPS_h_
源文件的一部分:
void FPS::initializeGraphicsTiles() {
//tile instance manager
uint16_t flags = Ogre::InstanceManagerFlags::IM_USEALL;
tileInstanceManager = mSceneMgr->createInstanceManager("InstanceManager", "tile.mesh", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::InstanceManager::HWInstancingVTF, 400, flags);
//fake tile
Ogre::Entity* entFakeTile = mSceneMgr->createEntity("Tile", "tile.mesh");
//initialize arrays
**tileSceneNode = new Ogre::SceneNode**[300];
**tileRigidBody = new btRigidBody**[300];
//tile
for (int x = 0; x <= 300; x++) {
*tileSceneNode[x] = new Ogre::SceneNode**[300];
*tileRigidBody[x] = new btRigidBody**[300];
for (int z = 0; z <= 300; z++) {
Ogre::InstancedEntity* entTile = tileInstanceManager->createInstancedEntity("Examples/Instancing/VTF/HW/Robot");
entTile->setCastShadows(true);
Ogre::SceneNode* tempNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();
tempNode->attachObject(entTile);
**tileSceneNode[x][z] = tempNode;
BtOgre::StaticMeshToShapeConverter converter(entFakeTile);
btConvexHullShape* mShape = converter.createConvex();
btScalar mass = 100;
btVector3 inertia;
BtOgre::RigidBodyState* state = new BtOgre::RigidBodyState(tempNode);
btRigidBody* tempBody = new btRigidBody(mass, state, mShape, inertia);
btTransform originalTransform;
tempBody->getMotionState()->getWorldTransform(originalTransform);
btVector3 originalOrigin = originalTransform.getOrigin();
originalOrigin.setX(originalOrigin.getX() + (x * 10.0));
originalOrigin.setZ(originalOrigin.getZ() + (z * 10.0));
originalTransform.setOrigin(originalOrigin);
tempBody->getMotionState()->setWorldTransform(originalTransform);
dynamicsWorld->addRigidBody(tempBody);
**tileRigidBody[x][z] = tempBody;
}
}
}
如果我删除(或大幅减少)双数组,则错误消失。
编辑:我知道我还没有清理内存,首先想让应用程序实际运行。答案 0 :(得分:3)
结帐sizeof(FPS)
。我猜它是相当大的(> 1MB)并且您在堆栈上分配FPS
本身的实例,对吧?您使用FPS app;
的位置,请将其替换为std::unique_ptr<FPS> app_ptr( new FPS );
,以解决您的问题。
答案 1 :(得分:1)
FPS
结构的大小约为1.4 MiB(sizeof(void *)* 2 * 300 * 300),如果您真的需要指向指向类的指针的2D指针数组,我就是怀疑糟糕的设计决定。
使用std::vector< std::vector< Ogre::SceneNode > > tileSceneNode;
可以大大减少您的内存麻烦
答案 2 :(得分:1)
我觉得你有点困惑。第一行声明了一个指向tileRigidBody的300x300指针指向指针的数组。
btRigidBody*** tileRigidBody[300][300];
所以,你有90,000个3 *指针。但是,你尝试做这样的事情,假设你有一个指向300指针300指针的指针......
**tileRigidBody = new btRigidBody**[300];
for (int x = 0; x <= 300; x++) {
*tileSceneNode[x] = new Ogre::SceneNode**[300];
*tileRigidBody[x] = new btRigidBody**[300];
使用std::vector<>
代替,事情会变得更加清晰!
如果必须使用数组(叹息......),那么请从以下内容开始: -
btRigidBody** tileRigidBody[300]; // 300 pointers to dynamic arrays
你的'init'看起来像这样(忽略了sceneNode的东西,类似): -
for (int x = 0; x < 300; x++)
{
tileRigidBody[x] = new btRigidBody*[300]; // create array of 300 pointers.
for (int z = 0; z < 300; z++)
{
....
btRigidBody* tempBody = new btRigidBody(mass, state, mShape, inertia);
tileRigidBody[x][z] = tempBody;
}
请注意for循环中的更改为< 300
- 您的代码溢出了数组。
警告 - 代码未经过测试,但您应该明白这一点。