构造函数内存泄漏引发的异常(句柄包装c ++)

问题描述 投票:0回答:2

我正在尝试编写DriverIterator类来遍历计算机中的所有卷。

我了解下一类可能会导致内存泄漏,因为:

current_ = std::make_unique<Driver>(paths);

可能会引发异常(由于某种原因。),因此构造将无法完成,结果析构函数将不会被调用,并且句柄将无法正确关闭。

当我取消设计时,一旦收到手柄,就应该停止构造。但是我该如何实现呢?FindFirstVolumeW还为我提供了在构造函数完成之前需要使用的数据。

DriverIterator.hpp:

class DriverIterator final
{
public:
    explicit DriverIterator();
     ~DriverIterator();

private:
    std::unique_ptr<Driver> current_;
    bool is_empty_;
    HANDLE handle_;

public:
    bool is_empty() const;
    Driver get_current() const;
    void next();

private:
    HANDLE start_find();

public:
    DriverIterator(const DriverIterator&) = delete;
    DriverIterator(DriverIterator&&) = delete;
    DriverIterator& operator=(const DriverIterator&) = delete;
    DriverIterator& operator=(DriverIterator&&) = delete;
};

DriverIterator.cpp:

DriverIterator::DriverIterator():
    handle_(start_find())
{}

DriverIterator::~DriverIterator()
{
    try
    {
        FindVolumeClose(handle_);
    }
    catch (...)
    {

    }
}

HANDLE DriverIterator::start_find()
{
    static constexpr uint32_t MAX_BUFFER_SIZE = 1024;
    wchar_t buffer[MAX_BUFFER_SIZE];

    HANDLE handle = FindFirstVolumeW(buffer, MAX_BUFFER_SIZE);
    if (handle == INVALID_HANDLE_VALUE)
    {
        //throw exception
    }

    wchar_t paths[1024];
    DWORD   res_size;

    if (!GetVolumePathNamesForVolumeNameW(buffer, paths, 1024, &res_size))
    {
        //throw exception
    }

    current_ = std::make_unique<Driver>(paths);

    is_empty_ = false;

    return handle;
}

bool DriverIterator::is_empty() const
{
    return is_empty_;
}

Driver DriverIterator::get_current() const
{
    if (is_empty_)
    {
        //throw exception
    }

    return *current_;
}

void DriverIterator::next()
{
    //code...
}
c++ winapi constructor memory-leaks raii
2个回答
0
投票

好,所以我创建了一个内部类'FindVolumeHandle来包装手柄。


0
投票

[如果从构造函数生成异常,则不调用对象析构函数,但是将调用已构造成员的析构函数,并释放为该对象分配的内存。

© www.soinside.com 2019 - 2024. All rights reserved.