下面的代码是否容易出现内存泄漏?

时间:2011-11-06 05:32:27

标签: c++ pointers

我是C ++的新手,我想知道下面的代码是否容易出现内存泄漏。 这里我使用std::ostream指针将输出重定向到控制台或文件。 为此我要为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;
}

还有一件事,我在调用ofstream的构造函数时没有关闭我打开的文件。我们是否有任何潜在的数据丢失情况。因为文件没有关闭。

4 个答案:

答案 0 :(得分:7)

是。当然。只要您在没有new的情况下致电delete,就会发生内存泄漏。

执行代码后,您需要添加以下内容:

        if(bDump)
        {
            delete osPtr;
        }

答案 1 :(得分:5)

由于@Mahmoud Al-Qudsi提到任何你必须删除的新内容,否则它将被泄露。

在大多数情况下,您想要使用删除,而是希望使用智能指针来自动删除对象。这是因为在异常的情况下你可以再次泄漏内存(而RAII),智能指针将保证删除对象,从而调用析构函数。

重要的是调用析构函数(特别是在这种情况下)。如果不调用析构函数,则可能不会将流中的所有内容刷新到基础文件。

#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. 

答案 2 :(得分:2)

是的,任何new但从未delete泄漏的内容。

在某些情况下,分配左右和中心,然后退出是完全合理的,特别是对于短命的批处理程序,但作为一般规则,您delete应该{{1} {}}和new你所有delete[]

特别是在上面的情况下,泄漏对象是不安全的,因为泄漏的对象是一个永远不会写出未刷新内容的ostream。

答案 3 :(得分:-1)

显示的代码没有泄漏。在执行期间的所有时间,所有分配的对象都是可引用的。如果已分配对象且无法以任何方式引用,则只会发生内存泄漏。

如果指针超出范围,或者其值被更改,而没有释放对象,那就是内存泄漏。但只要指针位于最外层范围内,没有其他任何东西改变它的值,就没有泄漏。

“在面向对象的编程中,当对象存储在内存中但运行代码无法访问时,会发生内存泄漏。” Wikipedia -- 'Memory leak'

其他答案表明,任何使用典型单例模式或在终止之前不释放所有已分配对象的程序都会发生内存泄漏。这是IMO,非常愚蠢。无论如何,如果你接受这个定义,几乎每个真实世界的程序或库都有内存泄漏,内存泄漏肯定不是全部都是坏的。

从某种意义上说,这种编码是倾向到内存泄漏,因为很容易改变指针的值或让它超出范围。在这种情况下,存在实际泄漏。但如图所示,没有泄漏。

您可能遇到了另一个问题:如果析构函数有副作用,则不调用它可能导致错误操作。例如,如果您从未在写入文件的缓冲输出流上调用析构函数,则最后一次写入可能永远不会发生,因为缓冲区未被刷新到文件中。

相关问题