How to properly remove stuff from memory?

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
turnip
Posts: 2
Joined: Tue Oct 18, 2022 1:54 pm

How to properly remove stuff from memory?

Post by turnip »

I am trying to figure out how to delete things that I have added to a scene manager so that I can free memory to make way for a new scene.

removing an irr::scene::IAnimatedMeshSceneNode* node like so: node->remove(); seems to work but I am still a bit unclear as to just what's happening.

(if say the node was created like so irr::scene::IAnimatedMeshSceneNode* node = smgr->addAnimatedMeshSceneNode( my_mesh );) then when I delete a node am I also deleting the associated mesh?
or do I have to do my_mesh()->drop(); or my_texture->drop();?

The long and short of my question is how are you supposed to delete(free memory from) the things used by irrlicht (nodes, meshes, textures etc) and if I delete a Scene node am I also deleting the things associated with that Scene node.

Thanks for any help, Tom.
CuteAlien
Admin
Posts: 9643
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: How to properly remove stuff from memory?

Post by CuteAlien »

node->remove removes the node from the SceneManager (or scene graph). If that's the only place that grab'ed the node then the node memory is gone.
If you did grab() the node somewhere yourself then the node stays until the last grab() is drop()'ed. It does not release memory of meshes or textures.

All meshes loaded with getMesh() are put into the mesh cache. ISceneManager::getMeshCache () allows you to access that. clear() in there would remove all meshes. Otherwise you can also go over caches meshes and remove them selectively.

Similar about textures. All texture stay cached - in this case directly in the IVideoManager (yeah.. no extra cache class there for historical reasons).
In theory you can call removeAllTextures (). But not always a good idea. Often better to remove them one-by-one. Or not at all - as different scenes very often tend to re-use the same textures.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
turnip
Posts: 2
Joined: Tue Oct 18, 2022 1:54 pm

Re: How to properly remove stuff from memory?

Post by turnip »

Thanks for the clarification.
So if I am not mistaken the following will allow me to free memory from textures, meshes and nodes:
irr::scene::IMeshCache* mesh_cache = smgr->getMeshCache();
mesh_cache->clear();
video_driver->removeAllTextures();
node->remove();
I seem to have no issues so far with the above.

But out of curiosity, is it incorrect to use the drop() functions for deleting textures/meshes etc?
I see that the drop() function is available for meshes and textures.

The below code gives no error until I close the window and then I get a segmentation fault.
and removing these lines stops the segmentation fault:
test_mesh->drop();
test_texture->drop();
node->remove();

#include <irrlicht.h>
#include <iostream>

int main()
{
irr::IrrlichtDevice *device =
irr::createDevice( irr::video::EDT_OPENGL, irr::core::dimension2d<irr::u32>(640, 480), 16,
false, false, false, 0);

if (!device)
return 1;

irr::video::IVideoDriver* video_driver = device->getVideoDriver();
irr::scene::ISceneManager* smgr = device->getSceneManager();

irr::scene::IAnimatedMesh* test_mesh = smgr->getMesh("irrlicht-1.8.5/media/sydney.md2");
if (!test_mesh)
{
device->drop();
return 1;
}
irr::scene::IAnimatedMeshSceneNode* node = smgr->addAnimatedMeshSceneNode( test_mesh );
irr::video::ITexture* test_texture = video_driver->getTexture("irrlicht-1.8.5/media/sydney.bmp");

if (node)
{
node->setMaterialFlag(irr::video::EMF_LIGHTING, false);
node->setMD2Animation(irr::scene::EMAT_STAND);
node->setMaterialTexture( 0, test_texture);
}
//These lines cause a segmentation fault upon exiting the program.
//but nothing happens until the program closes.
test_mesh->drop();
test_texture->drop();
node->remove();

smgr->addCameraSceneNode(0, irr::core::vector3df(0,30,-40), irr::core::vector3df(0,5,0));

while(device->run())
{
video_driver->beginScene(true, true, irr::video::SColor(255,100,101,140));

smgr->drawAll();

video_driver->endScene();
}

device->drop();

return 0;
}
CuteAlien
Admin
Posts: 9643
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: How to properly remove stuff from memory?

Post by CuteAlien »

grab() and drop() are about reference counted memory management. grab() increases a counter and drop() decreases it. When the counter reaches 0 the object is deleted. If you did not grab or create the object with new or with an Irrlicht function starting with the word "create" then do never call drop(). If you did any of that then you have to call drop() when you no longer need the pointer. Check IReferenceCounted documenation (it kinda says the same).

So grab'ing a reference means: I got a pointer to this object, please no one delete it until I drop it. If you call drop() without ever increase the reference counter, as you do above, then that all goes wrong. You're giving up a reference your object does not own and it deletes the object too early despite some other object thinking it still has a valid pointer. So the moment such an object accesses that pointer now, it's accessing invalid pointers.In your case the caches trying to drop those object when the device is released. If you are lucky that just causes a crash - that's at least easy to find.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
Post Reply