抛出异常后,对象内分配的指针是否自动解除分配

Does the allocated pointers inside an object are automatically deallocated after an exception is thrown?

本文关键字:是否 指针 解除分配 分配 对象 抛出异常      更新时间:2023-10-16

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

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

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

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

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

正确。

但是,在引发异常后,对象内分配的指针是否会自动释放?

不。但是,假设您谈论的是一个由于异常而被销毁的本地自动对象,那么应该设计该对象的析构函数,以便它解除分配该对象可能已分配的任何内存。

如果该本地对象只是一个指针,则指针不在对象内部。指针对象。常规指针在销毁时不会释放点内存。