Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Whether following code is prone to memory leak?

Tags:

c++

pointers

I am new to C++ and I want to know whether following code is prone to memory leak. Here I am using a std::ostream pointer to redirect output to either console or to a file. For this I am calling new operator for std::ofstream.

#include <iostream>
#include <fstream>

int main() {
    bool bDump;

    std::cout << "bDump bool" << std::endl;
    std::cin >> bDump;

    std::ostream *osPtr;

    if (bDump) {
        osPtr = new std::ofstream("dump.txt");
    } else {
        osPtr = &std::cout;
    }

    *osPtr << "hello";
    return 0;
}

And one more thing, I have not closed the file which I opened while calling constructor for ofstream. Do we have any potential data loss situation here. as file is not closed.

like image 550
Apoorva sahay Avatar asked Nov 06 '11 05:11

Apoorva sahay


2 Answers

Yes. Definitely. Any time you call new without delete, there's a memory leak.

After your code has executed, you need to add this:

        if(bDump)
        {
            delete osPtr;
        }
like image 146
Mahmoud Al-Qudsi Avatar answered Oct 20 '22 10:10

Mahmoud Al-Qudsi


As @Mahmoud Al-Qudsi mentioned anything you new must also be deleted otherwise it will be leaked.

In most situation you do not want to use delete but rather you want to use a smart pointer to auto-delete the object. This is because in situations with exceptions you could again leak memory (while RAII) the smart pointer will guarantee that the object is deleted and thus the destructor is called.

It is important the at the destructor is called (especially in this case). If you do not call the destructor there is a potential that the not everything in the stream will be flushed to the underlying file.

#include <iostream>
#include <fstream>

int doStuff()
{
    try
    {
        bool bDump;

        std::cout<<"bDump bool"<<std::endl;
        std::cin>>bDump;

        // Smart pointer to store any dynamic object.
        std::auto_ptr<std::ofstream>   osPtr;

        if(bDump)
        {
            // If needed create a file stream
            osPtr.reset(new std::ofstream("dump.txt"));
        } 

        // Create a reference to the correct stream.
        std::ostream&  log = bDump ? *osPtr : std::cout;

        log << "hello";
     }
     catch(...) {throw;}

 } // Smart pointer will correctly delete the fstream if it exists.
   // This makes sure the destructor is called.
   // This is guaranteed even if exceptions are used. 
like image 40
Martin York Avatar answered Oct 20 '22 11:10

Martin York