3

I have a simple question. I have an ofstream to which I write data. After I am done and call close(), do I need to call delete on the handle or does close() perform cleanup?

For example:

mFileStream = new std::ofstream(LogPath.c_str(), std::ios::trunc);
...
mFileStream->Close();
//delete mFileStream? 

My intuition is yes as I have allocated it, but I am not sure where I read it. Can anyone clarify?

KaiserJohaan
  • 9,028
  • 20
  • 112
  • 199
  • 2
    You need to call `delete` in this case. The object is allocated on the heap, `close()` just closes all the references to the actual file which are bound to this object. It doesn't handle cleanup of the actual object in any way. – Daniel Kamil Kozar Mar 02 '12 at 23:41

2 Answers2

8

Yes you have to. In C++ you must pair new and delete.

Though, in a simple case like this you don't need to, you can allocate your object on the stack and it will be destroyed for you, this is strongly recommended (faster and safer):

{ // enclosing scope (function, or control block)
    ofstream mFileStream(LogPath.c_str(), std::ios::trunc); 
    ... 
    mFileStream.close(); // mFileStream is not a pointer any more, use the "." operator
    // mFileStream destroyed for you here. "close" may even be called for you.
}

Small note: it is close with a small "c".

J.N.
  • 8,203
  • 3
  • 29
  • 39
0

All objects allocated with new must have a corresponding delete to avoid leaking. The same is true with new[] and delete[] (these happen to be separate operators, BTW).

As J.N. pointed out, in the code example above, you might as well use the stack and avoid operator new/delete. If the use of the stream is limited to some well-defined scope, there's no need to create your object on the free store (heap).

What you actually don't need here is the call to close. File streams already close when they are destroyed (in the destuctor) so it's fine to omit it. In fact, that's one of the big advantages of using file stream objects over fopen/fclose as we can see here: Do I need to manually close an ifstream?

Furthermore, if you use C++ the way Stroustrup encourages with strong conformance to his RAII idiom, you generally want to avoid writing code that needs to manually call delete all together. This might be a bit over your head at the moment, but we have smart pointers available in C++11 like shared_ptr and unique_ptr which will automatically destroy objects for us:

shared_ptr<ofstream> output_stream(new ofstream(...));
// ^^ This will not leak and the file will gracefully close
// when 'output_stream' is destroyed. It makes the need to
// call both delete and close unnecessary.

If you venture into the realm of C++ exception handling, you'll find this use of the destructor to clean up resources for you automatically is not only convenient but quite essential to coding safely and correctly.

Community
  • 1
  • 1
stinky472
  • 6,737
  • 28
  • 27