noob question - destructors - freeing memory...

S

someone

not sure exactlywhat you're up to here. But

- hiding standard libraries behind macros seems like a bad idea.
For a start it makes reading your code very difficult for other
people.

Ok, you're right... It was just a quick idea, so I didn't have to change
too much... It's/was a bad idea, I can see that now...
- what do you mean "a macro [...] that catches everything"?
(slightly paraphrashing you)

I mean, I have to "catch" whatever causes the program to quit and just
before it would otherwise quit, it has to cleanup and THEN quit (not
before having cleaned up).
As the other poster said calling exit() in a C++ is generally a bad
idea. It certainly precludes destrutors being called. I think the
effect you want could be had by throwing and not catching. This will
bubble all the way upto the top of the program, calling all the
relevent DTORs on the way. Then exiting.

I've googled a bit around... It's completely stupid: I use opengl / GLUT
and it seems, that if someone closes the glut-window, glut will call
exit(0), exit(1) or whatever... I read that freeGLUT however, doesn't
have this behaviour... It's ridiculous, isn't it?

With exit(0) from glut, is there any solution to cleaning up and freeing
memory?
there's something seriuslywrong if they aren't being called when
exceptions are thown!

Even if I figure out how to use exceptions: I think glut is not
"cleanup"-friendly... I can't believe that...

And the OS is not freeing the memory when exit(0) or exit(1) is called?

OS = linux, windows or mac...
post a simple, working program that illustrates your problem.

I'm not fully convinced that exceptions are the solution, so I cannot
show a simple working program yet.

What if the user pushes the "X" to close the glut-window and glut calls
exit() ? I know glut is not the scope of this group, but I hope someone
can clarify, because I'm not completely sure what to do now...
 
S

someone

This actually doesn't create an object, but declares a function d1
that returns a Derived object. If you compare

Derived d1();

to the more common

int f();

you will see the similarity!


Bo Persson

Ok, you're right... Then:

Derived d1;

Should be an object, that's what I think I meant :)
 
S

someone

would std::vector solve your problem? Something like this:-

Uuuuuh. sounds really ugly with a lot of overhead in my ears... Not sure
if it'll work, though...
// vec.cpp

#include<vector>

struct Point
{
int x;
int y;
int z;
};

void draw (std::vector<Point>& graphicalObject)
{
// do whatever has to be done to draw the object
}

// make an object with pointCount points
void makeObject (int pointCount)
{
std::vector<Point> graphicalObject(pointCount);
// initialise it somehow
draw (graphicalObject);
// graphicalObject and all its points destroyed here
}

int main ()
{
int n = 10; // determine number of points somehow
makeObject (n);
}

Replace n = 10 with n = 20.000. Also it needs to be really really fast
so openGL can make 60 FPS per seconds + all intermediate calculations...

You're saying that std::vector<> doesn't have the problem with not
cleaning up if there's an exit() somewhere, right?

Looks slow to me, but haven't tried it...
 
S

someone

std::auto_ptr

though I believe this is now deprecated. Hasn't been removed though
and does the job.

I'll try to google that, and look for working code examples - thanks...
 
S

someone

C++ does not implement garbage collection, which means that if you
allocate an object dynamically with 'new', you'll have to destroy it
explicitly with 'delete'. (Yes, I know that sucks, but either live with
it or switch to C#.)
Ok.

If you want the dynamically allocated object to be destroyed automatically
you'll have to use a smart pointer like std::shared_ptr to handle it. In
most cases, though, it's better to avoid the 'new' if you can, and instead

I don't think I can avoid it... I have some 20.000 points that needs
real fast access to screen buffer in opengl application...

I think "new" makes arrays of doubles (or floats) that are stored
consecutive in memory... I don't think C++ std::vector stores it's
values, consecutively in memory - does it?

Maybe I'm wrong... I think std::vector has overhead...
handle objects by value. When an object is handled by value it will be
scope-bound, and thus will be destroyed when its scope ends. In surprisingly
many cases (especially to people accustomed to languages like Java or C#),
you don't need 'new' to handle objects.

Ok, roger...
 
G

Garrett Hartshaw

Ooh, damn...

I hoped, I could avoid having to learn something new and timeconsuming
like boost...

Isn't there an easier solution without including more libraries?

Most of the smart pointers from boost are in std::tr1 in c++98 and
std in c++11,
if either std::tr1 or c++11 are supported by your complier. Otherwise
std::auto_ptr (not recommended, deprecated in c++11) or the boost
smart pointers should be used.
 
N

Nobody

I've googled a bit around... It's completely stupid: I use opengl / GLUT
and it seems, that if someone closes the glut-window, glut will call
exit(0), exit(1) or whatever... I read that freeGLUT however, doesn't
have this behaviour... It's ridiculous, isn't it?

With exit(0) from glut, is there any solution to cleaning up and freeing
memory?

The only thing I can think of is: call setjmp() in the main() function,
register an exit handler with atexit(), have the exit() handler longjmp()
back to main(), which just returns.

You can't just have the exit handler raise an exception because the exit
handler must have C linkage.

Also: note that exit() will invoke destructors of static objects, but not
those of automatic objects.
And the OS is not freeing the memory when exit(0) or exit(1) is called?

The OS will reclaim all resources used by the process upon termination.
Memory will be reclaimed, files closed, locks released, etc. However, any
user-space clean-up (e.g. flushing buffers, writing an epilogue to an
output file, deleting temporary files, etc) must be done by the
application.
 
N

Nobody

I don't think I can avoid it... I have some 20.000 points that needs
real fast access to screen buffer in opengl application...
?

I think "new" makes arrays of doubles (or floats) that are stored
consecutive in memory... I don't think C++ std::vector stores it's
values, consecutively in memory - does it?

It does.
Maybe I'm wrong... I think std::vector has overhead...

No more so than managing a dynamically-allocated array yourself. If you
know the number of entries in advance, you can use the resize() method to
create all elements. Thereafter, assignment of elements is no slower than
a "raw" array.

std::vector is only slower if you use features which aren't present in a
raw array, e.g. dynamically resizing the array as you add elements.
 
J

Juha Nieminen

someone said:
I don't think I can avoid it... I have some 20.000 points that needs
real fast access to screen buffer in opengl application...

What exactly does this have to do with derived classes and virtual
destructors?
 
L

LR

someone said:
I've googled a bit around... It's completely stupid: I use opengl / GLUT
and it seems, that if someone closes the glut-window, glut will call
exit(0), exit(1) or whatever... I read that freeGLUT however, doesn't
have this behaviour... It's ridiculous, isn't it?

Can you use freeGLUT?
With exit(0) from glut, is there any solution to cleaning up and freeing
memory?

Doesn't glut offer callbacks that allow you to capture information about
mouse and keyboard events? If so, you can use one of those to hook to
code that will call your destructors. You may have to expose your data
to a global pointer or something to do that though.

Even if I figure out how to use exceptions: I think glut is not
"cleanup"-friendly... I can't believe that...

And the OS is not freeing the memory when exit(0) or exit(1) is called?

OS = linux, windows or mac...

It might. Or your development environment might if you're building a
debug version, but I wouldn't count on it. And since you're worried
about performance, maybe that's not the way to go.
What if the user pushes the "X" to close the glut-window and glut calls
exit() ? I know glut is not the scope of this group, but I hope someone
can clarify, because I'm not completely sure what to do now...

Depends on if it can be captured per above.

Maybe glut isn't really the solution for you. There are a variety of
cross platform GUI toolkits for crossplatform apps. For example, I'm
pretty sure both wxWidgets and Qt have support for opengl and it's
possible both are available for the platforms you want to use. Best to
check that and licensing before you start.

Searching around on the web might be useful too. Maybe this would be of
interest? http://www.stetten.com/george/glutmaster/glutmaster.html I
found that link here: http://www.opengl.org/resources/libraries/glut/faq/
 
N

Nick Keighley

    - what do you mean "a macro [...] that catches everything"?
(slightly paraphrashing you)

I mean, I have to "catch" whatever causes the program to quit and just
before it would otherwise quit, it has to cleanup and THEN quit (not
before having cleaned up).

you could get destructors to do the cleanup. For instance a log file
could be an object and its dtor could flush the log file, write an
error message etc. Quite often catching is the wrong thing to do.
I've googled a bit around... It's completely stupid: I use opengl / GLUT
and it seems, that if someone closes the glut-window, glut will call
exit(0), exit(1) or whatever... I read that freeGLUT however, doesn't
have this behaviour... It's ridiculous, isn't it?

yes. Is there some way to stop it doing this?
With exit(0) from glut, is there any solution to cleaning up and freeing
memory?

as someone else said, use atexit() to register a cleanup function.

<snip>
 
N

Nick Keighley

Uuuuuh. sounds really ugly with a lot of overhead in my ears... Not sure
if it'll work, though...

I think it should.
Replace n = 10 with n = 20.000. Also it needs to be really really fast
so openGL can make 60 FPS per seconds + all intermediate calculations...

well new isn't cheap
You're saying that std::vector<> doesn't have the problem with not
cleaning up if there's an exit() somewhere, right?

vector calls the destructors for the objects it holds
 
N

Nick Keighley

Uuuuuh. sounds really ugly with a lot of overhead in my ears... Not sure
if it'll work, though...









Replace n = 10 with n = 20.000. Also it needs to be really really fast
so openGL can make 60 FPS per seconds + all intermediate calculations...

You're saying that std::vector<> doesn't have the problem with not
cleaning up if there's an exit() somewhere, right?

my earlier post was incorrect. exit() does not invoke any destructors.
idiot nick...
 
S

someone

Can you use freeGLUT?

Maybe... Just think it's strange that no good/easy solutions exists, if
I understand this correctly...
Doesn't glut offer callbacks that allow you to capture information about
mouse and keyboard events? If so, you can use one of those to hook to
code that will call your destructors. You may have to expose your data
to a global pointer or something to do that though.

I tried to do something like that.
Keyboard events: Yes, no problem.
Clicking "X" window: I think the OS forces a kill without being able to
capture anything...
It might. Or your development environment might if you're building a
debug version, but I wouldn't count on it. And since you're worried
about performance, maybe that's not the way to go.

So, like me you don't know if linux, windows or mac OS free's the memory
when exit(0) or exit(1) is called, and at least we don't count on it
unless somebody (in here?) says otherwise...
Depends on if it can be captured per above.

Maybe glut isn't really the solution for you. There are a variety of
cross platform GUI toolkits for crossplatform apps. For example, I'm
pretty sure both wxWidgets and Qt have support for opengl and it's
possible both are available for the platforms you want to use. Best to
check that and licensing before you start.

Hmm. Ok.
Searching around on the web might be useful too. Maybe this would be of
interest? http://www.stetten.com/george/glutmaster/glutmaster.html I
found that link here: http://www.opengl.org/resources/libraries/glut/faq/

Hmm. Maybe yes. Although I didn't for sure read that this would be much
better - it just says it's a C++ wrapper, but not much else...
 
S

someone

On 12/31/2011 06:56 AM, MikeWhy wrote:
someone wrote:
hmmmmmmmmmmmmmmmmmm. Maybe a quick solution is to #define a macro
exit(num), that does try and catch everytime I risk the program
otherwise would be calling exit(1) etc... hmmmmmmmmmmmmm....
- what do you mean "a macro [...] that catches everything"?
(slightly paraphrashing you)

I mean, I have to "catch" whatever causes the program to quit and just
before it would otherwise quit, it has to cleanup and THEN quit (not
before having cleaned up).

you could get destructors to do the cleanup. For instance a log file
could be an object and its dtor could flush the log file, write an
error message etc. Quite often catching is the wrong thing to do.

You're saying I should replace all my exit()-calls with something else,
I think too...
yes. Is there some way to stop it doing this?


as someone else said, use atexit() to register a cleanup function.

Ok, thanks - I'll look into that...
 
S

someone

No more so than managing a dynamically-allocated array yourself. If you
know the number of entries in advance, you can use the resize() method to
create all elements. Thereafter, assignment of elements is no slower than
a "raw" array.

Ok, nice to know...
std::vector is only slower if you use features which aren't present in a
raw array, e.g. dynamically resizing the array as you add elements.

Ok.
 
S

someone

Most of the smart pointers from boost are in std::tr1 in c++98 and std
in c++11,
if either std::tr1 or c++11 are supported by your complier. Otherwise
std::auto_ptr (not recommended, deprecated in c++11) or the boost smart
pointers should be used.

Ok, damn. I have to learn something new then and spend some time
understanding that... Only solution I see - thanks a lot for the hint!
 
S

someone

What exactly does this have to do with derived classes and virtual
destructors?

I just don't want static allocation, because only at runtime I know how
large arrays I need. So I'm saying I need dynamic allocation and I
cannot avoid that. Then std::vector<> and "new" both have the same
problem, with no cleaning up if there's an exit() somewhere.

As far as I can see, the solution is that I learn about smart pointers,
c++11 or std::tr1. And if that fails, I'll look at std::auto_ptr (though
not recommended from people in here)...
 
M

MikeWhy

someone said:
So, like me you don't know if linux, windows or mac OS free's the memory
when exit(0) or exit(1) is called, and at least we don't count on it
unless somebody (in here?) says otherwise...

Yes, we know for certain that Mac, Windows, and Linux/UNIX all release
memory held by the process when they terminate. They also release mutexes,
close files, sockets, and such. What isn't clear is whether your app leaves
the files and shared resources in a consistent state when you slam the
process. Device drivers and video libraries were once particularly fragile,
but that is mostly just a bad rememberance these days.

It can be that for some or even many apps, process cleanup by the OS is
sufficient. This should be a conscious choice, though, knowing what is safe
and what is not, rather than left to chance out of ignorance. Destructors
can do much more than simply release memory.

The largest problem in self-education is what you don't know about what you
need to know. It looks like you're coming to grips with process flow on
termination. You need to now understand more about what the OS thinks of a
process, its resources and lifetime. It's a long path, and aside from my
passing mention of destructors above, not language specific and probably
should be moved to a different newsgroup.
 
L

LR

I downloaded glut and played with it a little. atexit will probably work
for you.
I just don't want static allocation, because only at runtime I know how
large arrays I need.

How do you find out?



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.

// more stuff here...
// and then...
glutMainLoop();
}

Now when glutMainLoop calls exit, someData will be destroyed, and along
with it the memory that points contains.
So I'm saying I need dynamic allocation and I
cannot avoid that. Then std::vector<> and "new" both have the same
problem, with no cleaning up if there's an exit() somewhere.

I think std::vector is a little easier to deal with.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top