• 0

[C++] Close All Open Streams


Question

Is there a way in C++ to close all open streams without directly referencing the stream:

e.g. filestream.close();

I ask because I have a program where one of my file streams in not in scope when I call exit(-1) to terminate my program. The file stream is a member of a class and I would like to avoid having to pass around another reference to the class. Anyway to do something like:

cin:streams.close();

???

Lastly, does it even matter if I close it, or will it get closed by destructors when I call exit(-1)? Thanks

Link to comment
https://www.neowin.net/forum/topic/620937-c-close-all-open-streams/
Share on other sites

9 answers to this question

Recommended Posts

  • 0

If you're using gcc or STLport, it is automatically closed. From the gcc-3.4.5 (MinGW) header:

	  /**
	   *  @brief  The destructor closes the file first.
	  */
	  virtual
	  ~basic_filebuf()
	  { this->close(); }

You might look into your header files to determine the answer. That was found in the fstream header, so the code for the destructor might be in the same header.

  • 0
  rpgfan said:
If you're using gcc or STLport, it is automatically closed. From the gcc-3.4.5 (MinGW) header:

	  /**
	   *  @brief  The destructor closes the file first.
	  */
	  virtual
	  ~basic_filebuf()
	  { this->close(); }

You might look into your header files to determine the answer. That was found in the fstream header, so the code for the destructor might be in the same header.

But a destructor gets called when you either delete or go out of scope. Calling exit() does neither, it bypasses any C++ exit code that gets run when your program (main()) goes out of scope.

You can try it with the following code:

#include <stdlib.h>

#include <iostream>

class MyTest {
public:
	MyTest() { std::cout << "Constructor" << std::endl; }
	~MyTest() { std::cout << "Destructor" << std::endl; }
};

int main() {
	MyTest test;

	exit(-1);

	return 0;
}

First run without the exit(-1), then with and you'll see the difference. Basically, don't use exit() in C++.

  • 0

If I don't use exit(-1) to kill the program, is there some safer alternative that won't require exceptions or passing around a lot of extra variables?

Here's what I'm trying to do:

//Generic error message thrower and application exiter
void stopWithError(string s)
{
	cout << "ERROR: " << s << endl << "Terminating Parser.";
	Tokenizer *t = Tokenizer::Instance();  //Instance returns a Singleton, so this is good
	t->closeInput();
	//I have a ParseTree class that also has closeInput() function
	//, however, it doesn't use the Singleton
	//pattern, so I can't easily get a reference to the ParseTree class
	// -- and I call this function
	//from many different places.
	//I want to be able to do these 2 lines as well, but am not sure how to w/o passing
	//the parsetree object around all the time.  Is there any other way?
	//	 parsetree->closeInput();
	//	 delete parsetree;
	exit(1);
}

  • 0

You could make it so that each instance of your class adds an instance of the stream to a static vector. You could then add a static function that loops through the vector and closes everything.

Using a setjmp/longjmp back to main() (so that you could return and run all the destructors) would probably be an option as well.

  • 0
  itsnotabigtruck said:
You could make it so that each instance of your class adds an instance of the stream to a static vector. You could then add a static function that loops through the vector and closes everything.

I was thinking the same thing. Have a singleton with a factory method to allocate your streams and keep track of them, and a have a closeAll to close all your streams or a close method to close individual ones.

As for using setjmp/longjmp, avoid it for the same reason as exit(). You'll bypass destructors that get called when your functions go out of scope.

OP: Are you by any chance writing a compiler (I am)? If so, you could probably restructure your code to avoid all this hassle. Also, if you're catching and report errors in parsing and then quitting, it's better to try and recover from parsing errors than just quitting.

  • 0

Thanks for the static vector idea - I'll probably go with that due to my class deadline.

I am in fact writing an interpreter (not a compiler) for a made up language (oh boy). I'm very interested in the code restructuring idea. Can you explain what the general idea would be? Also, what are some general techniques for recovering from parsing errors without quitting? Do you have to be looser with your language grammar? Thanks.

This topic is now closed to further replies.
  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Posts

    • Simply the BEST email client I use it every single day . Phenomenal . It works with Gmail Aol for all out there to try it out !
    • It's been best practice for years to disable it anyway... TS disables 2.0, installs Pwsh 7.whatever
    • That's helpful, thanks. The key issue as I see it is that the issuer of the verification is still getting that request from WhateverNaughty.com, which immediately becomes a problem if this is a government issuer, etc. but it's a huge problem for any user with any issuer. I guess the solution, and maybe this goes without saying and I've missed it in your fine posts, is that the requester is also anonymized. That way, the issuer doesn't have a record of X person requested verification for Y website. And anyone who hacks that data is going to get precisely nothing. This only works is, as you say, this is a one-time challenge each time, and we all agree that no one is keeping/storing that data for any use anyway. After all, "is this person 18+ age" would only respond Yes/No, which is hardly actionable by anyone...as long as the asker only gets Yes/No and the Answerer doesn't know or care who's asking. :) Are both ends anonymized?
    • It definitely can be especially if you live in a dorm or frat/sorority house during your time in college. However, for many who live at home or in their own off campus residence and commute to classes it can be just about the classes. That is how it was for me. Except for classes, time in the library and some time in the student union mostly for eating and taking a break between classes, I was never on compus
  • Recent Achievements

    • First Post
      Celilo earned a badge
      First Post
    • One Year In
      K.I.S.S. earned a badge
      One Year In
    • Week One Done
      solidox earned a badge
      Week One Done
    • Dedicated
      solidox earned a badge
      Dedicated
    • Week One Done
      Devesh Beri earned a badge
      Week One Done
  • Popular Contributors

    1. 1
      +primortal
      441
    2. 2
      ATLien_0
      165
    3. 3
      +FloatingFatMan
      152
    4. 4
      Nick H.
      66
    5. 5
      +thexfile
      62
  • Tell a friend

    Love Neowin? Tell a friend!