I downloaded glut and played with it a little. atexit will probably work
for you.
Wow... I think I just made something much (much?) better!
I really hope you and the other clever guys in here can comment on my
newly found solution below!
I have some graphical objects and run some code, different from time to
time, showing different things. Based on what I want the program to
show, different geometries have to be drawn, requiring different vectors
of coordinates. I have some code that does a lot based on my input. It
then tells how large coordinate arrays I need. I then allocate that for
each geometry. Then I show that. ALSO: Better explanation: See below
---- bad explanation here, better below...
I didn't cut and paste this from working code.
Consider this,
struct SomeData {
std::vector<glVertex3f> points;
};
// global scope.
SomeData someData;
int main() {
// there are more efficient ways to do this.
// but maybe you should see how long this takes
// before you worry about it.
someData.points.push_back(glVertex3f(1.,2.,3.)); // or
whatever.
Actually my data (coordinates) comes from a fortran program. I link it
with my c++ (a bit C'ish though) program. I pass a pointer to an array
of double's for all X + Y + Z-values. I looks like:
----- C++ Program ----
extern "C" {
void getCoords_(...... const int *maxVectorSize,
double *cpp_X, double *cpp_Y, double *cpp_Z, int *some_id);
}
bla.bla.
getCoords_( &someInteger, &someOtherInteger, &maxVectorSize,
cpp_X, cpp_Y, cpp_Z, some_id);
====== Fortran Program =====
blabla.
----- C++ Program ----
blabla.
So I don't have the point in a vertex3f, although I'm thinking that I
can probably do something better than here and only pass 1
glVertex-coordinate to Fortran...
As you can see: I pass a pointer to the array of double's (maybe I
should change the fortran-code so it outputs the results as float, which
is used by opengl)...
// more stuff here...
// and then...
glutMainLoop();
}
Now when glutMainLoop calls exit, someData will be destroyed, and along
with it the memory that points contains.
My problem is more complicated than that, but my solution is perfectly
close to the idea in your suggested solution... I'll show my suggestion
I think std::vector is a little easier to deal with.
Maybe... I'm just a little bit stupid and afraid. So...
In my case: Using std::vector, would still allow me to pass a pointer to
arrays (of double or float) into a Fortran90 subroutine, which needs
pointers to the data so it can store the results... Is there any
problems here with std::vector???
What do you think?
======== here's my possible solution, please give some input ========
First: Short explanation... I have a class: drawableObj (base class)
from which all different geometries iherit.
As an example, I have a gear class that inherits from drawableObj.
Problem: Currently I only have a gear-class but later I want to have
other geometrical classes deriving from base class drawableObj, e.g.
maybe introduce a connecting "shaft"-class + a foundation + maybe sun +
stars + skyes + landscape etc. etc (all graphical objects derive from
base class drawableObj)...
I made it this way, because I wanted to introduce polymorphism in my
display()-function of my program... This makes it *REALLY* easy to
add/remove objects... See below... Enough introduction...
--- main.cpp ---
drawableObj allObjs; // must be global!
void display()
{
glClear(GL_COLOR_BUFFER_BIT);
...
// UPDATE ALL GRAPHICAL OBJS...
for (int z=0; z<(int) drawableObj:
Objs.size(); z++)
{
glPushMatrix();
((gearClass*) drawableObj:
Objs[z])->updateDisplay();
glPopMatrix();
}
..
glutSwapBuffers(); // also does glFlush();
}
int main(int argc, char** argv)
{
drawableObj *testGearPtr =
new gearClass( .... ); // rotSpeed etc, etc... bla.bla
drawableObj *testGearPtr2 =
new gearClass( .... ); // rotSpeed etc, etc... bla.bla
// Calculate INITIAL X+Y+Z points (only done once!)
for (int z=0; z<(int) drawableObj:
Objs.size(); z++)
{
((gearClass*) drawableObj:
Objs[z])->callFortran();
}
// ******* OpenGL starting... *******
glutInit(&argc, argv);
.... bla bla...
glutMainLoop(); // exits directly to OS from here...
return(0); // never comes here - just to satisfy compiler...
}
--- helper.h (#include guard not shown) ---
class drawableObj
{
// private: // protected: // I don't have anything here
public:
// global+static pointer to all GRAPHICAL objs:
static vector<drawableObj*> pObjs;
drawableObj(); // constructor
// destructor
virtual ~drawableObj();
// member functions
virtual void draw(); // <---used in openGL display loop
void showNumObjs();
void test();
};
--- gearClass.h (#include guard not shown) ---
class gearClass : public drawableObj
{
private:
public:
bool memAllocated; // IMPORTANT TO KNOW IF DELETE HAS BEEN CALLED
double *cpp_X, *cpp_Y, *cpp_Z;
bla bla...
virtual ~gearClass(); // destructor
// member functions
void deAllocate();
void callFortran();
void updateDisplay();
bla.bla
};
--- helper.cpp ---
#include "helper.h"
#include "gearClass.h" // for knowing "gearClass"-type
// NOT SURE ABOUT THIS, BUT COMPILER COMPLAINS IF NOT "EXTERN"...
extern vector<drawableObj*> drawableObj:
Objs;
drawableObj::~drawableObj() // destructor
{
int numObj = pObjs.size();
if (numObj == 0)
cout << " Destructing base (drawableObj), " <<
"no objects left: #objects: " <<
numObj << endl << endl;
else
{
cout << endl << "---- NB: BASE IS BEING DESTROYED, " <<
"BUT DERIVED OBJECTS MUST ALSO DIE ----" << endl;
int numObjs = (int) drawableObj:
Objs.size();
cout << "---- Number of obj's to delete: " << numObjs <<
" ----" << endl;
for (int z=0; z<numObjs; z++)
{
if ( ((gearClass*) drawableObj:
Objs[z])->memAllocated )
delete ((gearClass*) drawableObj:
Objs[z]);
}
}
}
--- gearClass.cpp ---
gearClass::gearClass() // constructor
{
drawableObj:
Objs.push_back((gearClass*) this); // ISN'T THIS NICE ??
... bla bla...
cpp_X = new double[maxVectorSize]; // NEEDS TO BE FREE'd BY DESTRUCTOR
cpp_Y = new double[maxVectorSize]; // NEEDS TO BE FREE'd BY DESTRUCTOR
cpp_Z = new double[maxVectorSize]; // NEEDS TO BE FREE'd BY DESTRUCTOR
memAllocated = true; // need to know if allocated or not...
}
gearClass::~gearClass() // destructor
{
if (memAllocated)
{
deAllocate();
drawableObj:
Objs.pop_back(); // REMOVE 1 COUNT...
cout << "Derived: gearClass::~gearClass() has free'd memory..." << endl;
memAllocated = false;
}
}
void gearClass::deAllocate()
{
cout << " (deallocating cpp_X, cpp_Y and cpp_Kontur_id)" << endl;
delete [] cpp_X;
delete [] cpp_Y;
delete [] cpp_Z;
}
======== that was possible solution, please give some input ========
Final remarks:
This code seem to clean up everything, by calling the destructors and
de-allocating correcty (because I have the global drawableObj allObjs in
top of main(), I think - isn't that right?)... Even if I use exit(0) or
exit(1), it cleans up, I think... Please tell me if I've made any error
somewhere, that I haven't seen... Also please write suggestions, if
something can be improved in ANY way!
Thank you, all!