Reputation: 910
I am not sure if the following code is safe from memory leak.
#ifndef RENDERABLE_H
#define RENDERABLE_H
class QGLShaderProgram;
class GLWidget;
class BoundingBox;
class Renderable{
public:
virtual void update(float duration) = 0;
virtual void render(QGLShaderProgram& shader, float duration) = 0;
virtual BoundingBox* getBBox() const = 0;
virtual void translate(float xx, float yy, float zz) = 0;
virtual void rotate(float degrees_x, float degrees_y, float degrees_z) = 0;
virtual void scale(float xx, float yy, float zz) = 0;
};
#endif // RENDERABLE_H
The above "interface" is been implemented by object3d.cpp. We may then add many Object3D objects into a Scene object if they belong to the same scene. However, upon the end of the scene, I want to ensure there is no memory leak and so I would call delete on everything. However, in the scene object, I have the following variable:
QVector<Renderable*>* sceneObjects;
QVector<GLTexture2D*>* sceneTextures;
QMap<QString, Material*>* sceneMaterials;
As you can see,
delete sceneObjects;
delete sceneTextures;
delete sceneMaterials;
should delete the QVector and according to Qt, it should call the destructor of those objects in it. However, Qt documentation were not clear about object POINTERS. Would Qt delete object pointers with their proper destructor? Additionally, what happens to Renderable pointers? As you can see from the "interface" that it has no destructor.
Thanks for any input. ChaoSXDemon
Upvotes: 1
Views: 380
Reputation: 51920
You need to delete each pointer manually. You don't need to iterate over every one manually though. You can do this very easily with:
qDeleteAll(*sceneObjects);
delete sceneObjects;
Same for your other containers. qDeleteAll
is documented here: http://doc.qt.digia.com/qt/qtalgorithms.html#qDeleteAll-2
Also add a virtual dtor, as Seth Carnegie mentioned.
Upvotes: 2
Reputation: 75150
First of all, your Renderable
class must have a virtual destructor, because calling delete
on a base pointer to a derived object is undefined behaviour without one.
Second, no, you will need to loop through and call delete
on each pointer (or, as Nikos noted, use qDeleteAll
as long as every object in the container is allocated with plain new
(and not new[]
or malloc
or anything else)) in each container to make sure their memory is reclaimed (how could Qt know if the pointers point to things allocated by new
? They could point to things allocated by new[]
, things on the heap, the stack, or somewhere else).
If you don't want to do that, you can store unique_ptr
s in the containers and then the destructors of the unique_ptr
s will be called when you delete
the containers, and those destructors will deallocate the memory they own. No need to manually deallocate them or use qDeleteAll
.
Upvotes: 5