【问题标题】:Does the allocated pointers inside an object are automatically deallocated after an exception is thrown?抛出异常后,对象内部分配的指针是否会自动释放?
【发布时间】:2016-06-19 08:08:12
【问题描述】:

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

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... */
    }
};

【问题讨论】:

  • TL;DR;您使用new 创建的任何内容都不会被自动删除,这代表您。这就是你不应该这样做的主要原因。
  • new 只是创建内存,如果您想要描述的行为,请尝试使用 RAII,例如 std::unique_ptr,这是一个堆栈对象,其中有一个析构函数,其中调用了 delete。跨度>

标签: c++ exception memory-leaks


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    我知道局部变量和对象在异常发生后被释放

    正确。

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

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

    如果该本地对象只是一个指针,则指针不在对象内部。指针的对象。普通指针在销毁时不会释放指向的内存。

    【讨论】:

      猜你喜欢
      • 2017-05-07
      • 2010-11-21
      • 1970-01-01
      • 2011-11-15
      • 1970-01-01
      • 2016-04-01
      • 1970-01-01
      • 2014-04-03
      • 1970-01-01
      相关资源
      最近更新 更多