Jump to content
  • Advertisement
Sign in to follow this  
dingojohn

Unity Custom ostreams and memory allocation

This topic is 4252 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I am writing a logger right now which is based on the approach proposed by Bregma in this thread. It works like a charm, and I have modified it quiet a bit to fit my needs exactly. I feel that I, before using it in a larger project, have to make sure that it is completely error free. And my first concern is a memory leak. I have this function:
[source lang="cpp]/*
Creates a logstream used by which, directed at where
*/
void log::make(std::ostream& which, std::ostream& where) {
	which.rdbuf(new log::logstream<char>(where.rdbuf()));
	
} // log is the namespace"
And I'm fairly sure that the STL streams do not free the memory I allocate here. Please correct me, if that is not the case. The question is now, what would be the ideal way to make sure, that it is free'ed at a later stage, when I don't need the logstream. Should I give the user of the lib the responsibility by returning a void* to the allocated memory, or should I find a way to wrap it into the logstream class? The last option seems quite hard to do, since the ofstream I create is associated with the ostream "which" - eg, std::cout.rdbuf(new) , std::cerr.rdbuf(new) etc. I hope I make myself clear.

Share this post


Link to post
Share on other sites
Advertisement
For a normal stream, you can register a callback (std::ios_base::register_callback()) that should receive the std::ios_base::erase_event event when the stream is destroyed. At that point you can do a dynamic_cast on the rdbuf() and delete it if it's yours.

For one of the standard streams (cin, cout, cerr, clog), they never get destroyed so such a callback will not usually get invoked. My take on that is that it's not a memory leak so much as a permanent allocation on the free store. It's not a leak if it was intentional and does not grow.

If you plan to replace the streambuf for a stream more than once, you can do a dynamic_cast on the rdbuf() in your log::make function and delete the old buffer if it's one of yours.

--smw

Share this post


Link to post
Share on other sites
Thanks for the fast answer. And also quite nice to see the original author of the code answering.

Quote:
Original post by Bregma
If you plan to replace the streambuf for a stream more than once, you can do a dynamic_cast on the rdbuf() in your log::make function and delete the old buffer if it's one of yours.

--smw


How would I, in my log::make function know whether it is my own before doing the dynamic cast? There is no RTTI for that - as far as I know - and normally some sort of RTTI is what I use for determining what to cast the object into. And I cannot just delete everything since that would also cause trouble.

@ Bregma: What did you do?

Share this post


Link to post
Share on other sites
Quote:
Original post by dingojohn
How would I, in my log::make function know whether it is my own before doing the dynamic cast? There is no RTTI for that - as far as I know - and normally some sort of RTTI is what I use for determining what to cast the object into. And I cannot just delete everything since that would also cause trouble.

You do the dynamic_cast to see if it is your own before you delete it. Maybe like this (off the top of my head).

void log::make(std::ostream& which, std::ostream& where) {
std::streambuf* oldbuf = which.rdbuf(new log::logstream<char>(where.rdbuf()));
logstream<char>* mybuf = dynamic_cast<logstream<char>*>(oldbuf);
if (mybuf) delete mybuf; // only delete what you new.
}

Quote:

@ Bregma: What did you do?

Me, I only ever use std::cerr and std::clog and replace them once at the beginning of a program. Like I say I don't consider that situation a memory leak.

--smw

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!