抛出异常后,对象内的已分配指针是否会自动释放?

时间:2016-03-05 14:54:31

标签: c++ exception memory-leaks

实际上我使用以下方法确保在我的对象中抛出异常时正确清理了我的缓冲区,但它需要比下面的示例更多的代码。

class Foo
{
private:
    int m_bufferSize;
    char m_isNetBufferSet;
    char* m_netBuffer;

    setBufferSize(const int bufferSize)
    {
        if (!m_isNetBufferSet)
        {
            m_bufferSize = bufferSize;
            m_netBuffer = new char[m_bufferSize];
            ZeroMemory(m_netBuffer, m_bufferSize);
        }
    }

    freeBuffer()
    {
        if (m_isNetBufferSet)
        {// i'm not using m_netBuffer != NULL because i'm not sure how it behave
            delete [] m_netBuffer;
            m_isNetBufferSet    = 0;
            m_bufferSize        = 0;
        }
    }

public:
    Foo()
    {
        m_isNetBufferSet    = 0;
        m_bufferSize        = 0;
        m_netBuffer         = NULL;
    }

    bar()
    {
        std::wstring hello(L"Hey, how are you?");

        freeBuffer();
        setBufferSize(hello.size() * sizeof(wchar_t));

        throw std::runtime_error("Oh noes something suddenly went wrong :(");

        /* never reached... */
    }

    ~Foo()
    {
        freeBuffer();
    }
};

我知道局部变量和对象在异常后被释放,但是在抛出异常后,对象内部分配的指针会自动释放吗? 是否可以通过执行以下操作来简化我的代码而不会造成内存泄漏?

class Foo
{
public:
    bar()
    {
        std::wstring hello(L"Hey, how are you?");
        char *netBuffer = new char[hello.size() * sizeof(wchar_t)];

        throw std::runtime_error("Oh noes something suddenly went wrong :(");

        /* never reached... */
    }
};

2 个答案:

答案 0 :(得分:2)

当抛出异常时,将调用已在堆栈中分配的所有内容的析构函数。使用new创建的对象不在堆栈上,而是在堆上,并且不会隐式删除。您需要确保自己删除它们。

要自动删除此类对象,建议在c ++ 11/14中使用RAII或某些智能指针,如std::unique_ptrstd::shared_ptr。但是,在您的情况下,您可能需要考虑使用std::vector<char>std::string

答案 1 :(得分:0)

  

我知道在异常

之后释放了局部变量和对象

正确。

  

但抛出异常后,对象内部分配的指针会自动释放吗?

没有。但假设您正在讨论由于异常而被销毁的本地自动对象,那么应该设计对象的析构函数,以便释放对象可能已分配的任何内存。

如果该本地对象只是一个指针,那么指针不在里面该对象。指针对象。常规指针在销毁时不会释放指向的内存。