如何安全释放构造函数分配的资源?

时间:2019-03-26 11:24:56

标签: c++ oop

我使用C函数,该函数应将文本写入构造函数中分配的缓冲区。问题是我需要将字符串传递给异常构造函数,但是在创建异常后,分配给文本的内存将丢失:

class SomeClass{
public:
    SomeClass(){
        //important code ->
        //...
        //<- important code

        if(0 != some_func_to_get_error()){
            int bufferLen = some_func_to_get_buff_len();
            char* bufferText = new char[bufferLen + 1];
            some_func_to_get_text(bufferText, bufferLen); //contains error text
            throw runtime_error(bufferText); //exit from constructor body
            //???
        }
    }
};

现在,文本丢失在某处。请告诉我如何解决这个问题。

2 个答案:

答案 0 :(得分:0)

我假设您上面的代码中的runtime_error是指std::runtime_error?在这种情况下,您可以简单地将其传递给std::string并释放缓冲区。例如

int bufferLen = some_func_to_get_buff_len();
auto bufferText = std::unique_ptr<char[]> { new char[bufferLen + 1] };
some_func_to_get_text(bufferText.get(), bufferLen);
throw runtime_error({ bufferText.get(), bufferText.get() + bufferLen });

或者,定义您自己的异常类型:

#include <utility>
#include <exception>
#include <memory>


class my_error : public std::exception
{
    std::unique_ptr<char[]> msg;

public:
    my_error(std::unique_ptr<char[]>&& msg) noexcept
      : msg(std::move(msg))
    {
    }

    const char* what() const noexcept override
    {
        return msg.get();
    }
};

…

int bufferLen = some_func_to_get_buff_len();
auto bufferText = std::unique_ptr<char[]> { new char[bufferLen + 1] };
some_func_to_get_text(bufferText.get(), bufferLen);
throw my_error(std::move(bufferText));

定义自己的异常类型的主要优点是,它允许分别处理这些类型的错误。额外的好处是它还避免了复制错误字符串。由于例外情况只应在特殊情况下发生,因此这实际上不是问题……

答案 1 :(得分:0)

通常,与大多数资源分配一样,可以使用容器来处理这种情况。字符串的标准容器是std::string

// add + 1 to bufferLen if using older standard than C++17
std::string bufferText(bufferLen);

当字符串被销毁时,它将重新分配其内部缓冲区。